summaryrefslogtreecommitdiff
path: root/elpa/smartparens-20200324.2147/smartparens-ess.el
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/smartparens-20200324.2147/smartparens-ess.el')
-rw-r--r--elpa/smartparens-20200324.2147/smartparens-ess.el227
1 files changed, 227 insertions, 0 deletions
diff --git a/elpa/smartparens-20200324.2147/smartparens-ess.el b/elpa/smartparens-20200324.2147/smartparens-ess.el
new file mode 100644
index 0000000..3afbdd5
--- /dev/null
+++ b/elpa/smartparens-20200324.2147/smartparens-ess.el
@@ -0,0 +1,227 @@
+;;; smartparens-ess.el --- Smartparens Extension for Emacs Speaks Statistics -*- lexical-binding: t; -*-
+
+;; Copyright (c) 2015-2016 Bernhard Pröll
+
+;; Author: Bernhard Pröll
+;; Maintainer: Bernhard Pröll
+;; URL: https://github.com/Fuco1/smartparens
+;; Created: 2015-02-26
+;; Version: 0.2
+;; Keywords: abbrev convenience editing
+
+;; This file is NOT part of GNU Emacs.
+
+;; 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 provides some additional configuration for ESS. To use
+;; it, simply add:
+;;
+;; (require 'smartparens-ess)
+;;
+;; into your configuration. You can use this in conjunction with the
+;; default config or your own configuration.
+;;
+;;; Code:
+
+(require 'smartparens)
+(require 'rx)
+
+(defvar ess-roxy-str)
+
+(declare-function ess-roxy-indent-on-newline "ess-roxy")
+
+
+(dolist (mode '(ess-mode ess-r-mode inferior-ess-mode inferior-ess-r-mode))
+ ;; avoid traveling commas when slurping
+ ;; (|a, b), c ---> (|a, b, c)
+ (add-to-list 'sp-sexp-suffix (list mode 'regexp ""))
+ ;; `sp-sexp-prefix' for ESS
+ (add-to-list 'sp-sexp-prefix
+ (list mode 'regexp
+ (rx (zero-or-more (or word (syntax symbol)))))))
+
+;; slurping follows Google's R style guide
+;; see https://google.github.io/styleguide/Rguide.xml
+(defun sp-ess-pre-handler (_id action _context)
+ "Remove spaces before opening parenthesis in a function call.
+Remove redundant space around commas.
+ID, ACTION, CONTEXT."
+ (when (equal action 'slurp-forward)
+ (let ((sxp (sp-get-thing 'back)))
+ (save-excursion
+ (goto-char (sp-get sxp :beg-prf))
+ ;; (|) x ---> (x)
+ (when (looking-back (rx (syntax open-parenthesis)
+ (one-or-more space)) nil)
+ (cycle-spacing 0 nil 'single-shot))
+ (cond
+ ;; (|)if(cond) ---> (|if (cond))
+ ((member (sp-get sxp :prefix) '("if" "for" "while"))
+ (goto-char (sp-get sxp :beg))
+ (cycle-spacing 1 nil 'single-shot))
+ ;; (|)v [,2] <- if(x > 1) ---> (v[,2] <- if (x > 1))
+ ((and
+ (member (sp-get sxp :op) '("[" "("))
+ (equal (sp-get sxp :prefix) "")
+ (looking-back
+ (rx (and (not-char "%" ",")
+ (not (syntax close-parenthesis)))
+ (one-or-more space)) nil)
+ (not (member
+ (save-excursion
+ (sp-backward-sexp)
+ (thing-at-point 'word 'noprop))
+ '("if" "for" "while"))))
+ (cycle-spacing 0 nil 'single-shot))
+ ;; (|[...])%in% ---> ([...] %in%|)
+ ((or (looking-at "%") (looking-back "%" nil))
+ (just-one-space))
+ ;; (|)a , b, c ---> (|a, b, c)
+ ((looking-back
+ (rx (zero-or-more space) "," (zero-or-more space))
+ (line-beginning-position) 'greedy)
+ (replace-match ", "))))))
+ (when (equal action 'slurp-backward)
+ (let ((sxp (sp-get-thing)))
+ (save-excursion
+ (goto-char (sp-get sxp :end))
+ ;; x (|) ---> (x)
+ (when (looking-at (rx (one-or-more space)
+ (syntax close-parenthesis)))
+ (cycle-spacing 0 nil 'single-shot))
+ ;; if(cond){} (|) ---> (if (cond) {}|)
+ (cond ((member (sp-get sxp :prefix) '("if" "for" "while"))
+ (goto-char (sp-get sxp :beg))
+ (cycle-spacing 1 nil 'single-shot))
+ ;; for style reasons there should be a space before curly
+ ;; brackets and binary operators
+ ((and (member (sp-get sxp :op) '("{" "%"))
+ (not (looking-at (rx (syntax close-parenthesis)))))
+ (cycle-spacing 1 nil 'single-shot))
+ ;; v[2](|) ---> (v[2]|)
+ ((and
+ (not (member (thing-at-point 'word 'noprop)
+ '("if" "for" "while")))
+ (looking-at
+ (rx (and (zero-or-more space)
+ (not-char "{")
+ (or (syntax close-parenthesis)
+ (char "(")
+ (char "["))))))
+ (cycle-spacing 0 nil 'single-shot))
+ ;; 1 , 2 (|) ---> (1, 2)
+ ((looking-at
+ (rx (zero-or-more space) "," (zero-or-more space)))
+ (replace-match ", ")))))))
+
+;; function(x) {|} ---> function(x) {\n|\n}
+;; ##' \tabular{rrr}{|} --->
+;; ##' \tabular{rrr}{
+;; ##' |
+;; ##' }
+(defun sp-ess-open-sexp-indent (&rest _args)
+ "Open new brace or bracket with indentation.
+ARGS."
+ (if (and (fboundp 'ess-roxy-entry-p) (ess-roxy-entry-p))
+ (progn
+ (save-excursion (ess-roxy-indent-on-newline))
+ (when (looking-back ess-roxy-str nil)
+ (cycle-spacing 3 nil t)))
+ (newline)
+ (indent-according-to-mode)
+ (forward-line -1)
+ (indent-according-to-mode)))
+
+(defun sp-ess-roxy-str-p (_id action _context)
+ "Test if looking back at `ess-roxy-re'.
+ID, ACTION, CONTEXT."
+ (when (and (boundp 'ess-roxy-re) (eq action 'insert))
+ (sp--looking-back-p ess-roxy-re)))
+
+(sp-with-modes 'ess-mode
+ (sp-local-pair "{" nil
+ :pre-handlers '(sp-ess-pre-handler)
+ ;; the more reasonable C-j interferes with default binding for
+ ;; `ess-eval-line'
+ :post-handlers '((sp-ess-open-sexp-indent "M-j")))
+ (sp-local-pair "(" nil
+ :pre-handlers '(sp-ess-pre-handler)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j")))
+ (sp-local-pair "[" nil
+ :pre-handlers '(sp-ess-pre-handler)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j")))
+ (sp-local-pair "'" nil
+ :unless '(sp-ess-roxy-str-p sp-in-comment-p sp-in-string-quotes-p)))
+
+;;; roxygen2 markup
+;; see https://cran.r-project.org/web/packages/roxygen2/vignettes/formatting.html
+(sp-with-modes 'ess-mode
+ (sp-local-pair "\\strong{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\strong")
+ (sp-local-pair "\\emph{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\emph")
+ (sp-local-pair "\\code{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\code")
+ (sp-local-pair "\\url{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\url")
+ (sp-local-pair "\\link{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\link")
+ (sp-local-pair "\\href{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\href"
+ :suffix "{[^}]*}")
+ (sp-local-pair "\\email{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\email")
+ (sp-local-pair "\\pkg{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\pkg")
+ (sp-local-pair "\\item{" "}"
+ :when '(sp-in-comment-p)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j"))
+ :trigger "\\item{")
+ (sp-local-pair "\\enumerate{" "}"
+ :when '(sp-in-comment-p)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j"))
+ :trigger "\\enumerate")
+ (sp-local-pair "\\itemize{" "}"
+ :when '(sp-in-comment-p)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j"))
+ :trigger "\\itemize")
+ (sp-local-pair "\\describe{" "}"
+ :when '(sp-in-comment-p)
+ :post-handlers '((sp-ess-open-sexp-indent "M-j"))
+ :trigger "\\describe")
+ (sp-local-pair "\\eqn{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\eqn")
+ (sp-local-pair "\\deqn{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\deqn")
+ (sp-local-pair "\\tabular{" "}"
+ :when '(sp-in-comment-p)
+ :trigger "\\tabular"
+ :post-handlers '((sp-ess-open-sexp-indent "M-j"))
+ :suffix "{[^}]*}"))
+
+
+(provide 'smartparens-ess)
+;;; smartparens-ess ends here
Copyright 2019--2024 Marius PETER