add lisp packages

This commit is contained in:
2020-12-05 21:29:49 +01:00
parent 85e20365ae
commit a6e2395755
7272 changed files with 1363243 additions and 0 deletions

11
lisp/ess/.dir-locals.el Normal file
View 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

File diff suppressed because it is too large Load Diff

768
lisp/ess/announc.info Normal file
View 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 Milkypostmans 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

8
lisp/ess/ess-defs.info Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

257
lisp/ess/ess-jags-d.el Normal file
View 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
View 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
View 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
View 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:

View 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
View 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

File diff suppressed because it is too large Load Diff

590
lisp/ess/ess-r-package.el Normal file
View 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

File diff suppressed because it is too large Load Diff

145
lisp/ess/ess-r-xref.el Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

531
lisp/ess/ess-s-lang.el Normal file
View 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

File diff suppressed because it is too large Load Diff

334
lisp/ess/ess-sas-d.el Normal file
View 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

File diff suppressed because it is too large Load Diff

65
lisp/ess/ess-site.el Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

232
lisp/ess/ess-trns.el Normal file
View 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

File diff suppressed because it is too large Load Diff

227
lisp/ess/ess.el Normal file
View 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

File diff suppressed because it is too large Load Diff

185
lisp/ess/essd-els.el Normal file
View 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

Binary file not shown.

10
lisp/ess/etc/ESSR/BUILDESSR Executable file
View 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")

View 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)
})
})

View 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))
}

View 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)
}

View 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
View 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
View 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
View 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)
}

View 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
View 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
View 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
View 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
View 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
View 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.

View 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..."};

View 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....",
"........................"};

View File

@@ -0,0 +1,30 @@
/* XPM */
static char *rline[]={
"24 24 3 1",
". c None s backgroundToolBarColor",
"a c #000000",
"# c #1532ed",
"........................",
"...............#........",
"...............##.......",
".....#############......",
".....##############.....",
".....#############......",
"...............##.......",
"...............#........",
"........................",
"........................",
"........................",
"........................",
"........................",
"........................",
"........................",
"........................",
"........................",
"...aaaaaaaaaaaaaaaaaa...",
"........................",
"........................",
"........................",
"........................",
"........................",
"........................"};

View 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...",
"........................",
"........................",
"........................"};

View 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"};

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View 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"
};

View 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"};

View 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"
};

View 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....",
"................................................",
"................................................"
};

View 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..",
"..###...................",
"..###...................",
"..###...................",
"..###...........#.......",
"..###...........##......",
"..#################.....",
"..##################....",
"...################.....",
"................##......",
"................#......."};

View 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"};

View 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
View 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
View 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
View 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

View 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

View 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

View 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

View 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

View 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
View 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

File diff suppressed because it is too large Load Diff

775
lisp/ess/readme.info Normal file
View 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 Milkypostmans 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
View 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