Files
emacs.d/elpa/ess-smart-underscore-20170222.1715/ess-smart-underscore.el
Mateus Pinto Rodrigues 2362e805bd Add new packages installed
2018-03-27 20:52:59 -03:00

374 lines
13 KiB
EmacsLisp

;;; ess-smart-underscore.el --- Ess Smart Underscore
;;
;; Filename: ess-smart-underscore.el
;; Description: ess-smart-underscore
;; Author: Matthew L. Fidler
;; Maintainer: Matthew Fidler
;; Created: Thu Jul 14 11:04:42 2011 (-0500)
;; Version: 0.79
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500)
;; By: Matthew L. Fidler
;; Update #: 137
;; URL: http://github.com/mlf176f2/ess-smart-underscore.el
;; Package-Requires: ((ess "0"))
;; Keywords: ESS, underscore
;; Compatibility:
;;
;; Features that might be required by this library:
;;
;; `custom', `easymenu', `ess', `ess-compat', `ess-custom',
;; `font-lock', `syntax', `widget'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; * Installation
;;
;; To use without using a package manager:
;;
;; - Put the library in a directory in the emacs load path, like ~/.emacs.d
;; - Add (require 'ess-smart-underscore) in your ~/.emacs file
;;
;; This is in emacswiki, so this package can also be installed using el-get.
;;
;; After installing el-get, Type M-x el-get-install ess-smart-underscore.
;; * Ess-Smart Underscore Package Information
;; Smart "_" key: insert `ess-S-assign', unless:
;;
;; 1. in string/comment
;; 2. after a $ (like d$one_two) (toggle with `ess-S-underscore-after-$')
;; 3. when the underscore is part of a variable definition previously defined.
;; (toggle with `ess-S-underscore-after-defined')
;; 4. when the underscore is after a "=" or "<-" on the same line.
;; 5. inside a parenthetical statement () or [].
;; (toggle with `ess-S-underscore-when-inside-paren')
;; 6. At the beginning of a line.
;; 7. In a variable that contains underscores already (for example foo_a)
;; (toggle with `ess-S-underscore-when-variable-contains-underscores')
;; 8. The preceding character is not a tab/space (toggle with
;; `ess-S-underscore-when-last-character-is-a-space'. Not enabled
;; by default.)
;;
;; An exception to
;;
;;
;; a <- b |
;;
;;
;; Pressing an underscore here would produce
;;
;;
;;
;; a <- b <-
;;
;;
;; However when in the following situation
;;
;;
;; a <- b|
;;
;;
;; Pressing an underscore would produce
;;
;;
;; a <- b_
;;
;;
;; This behavior can be toggled by `ess-S-space-underscore-is-assignment'
;;
;; If the underscore key is pressed a second time, the assignment
;; operator is removed and replaced by the underscore. `ess-S-assign',
;; typically " <- ", can be customized. In ESS modes other than R/S,
;; an underscore is always inserted.
;;
;; In addition the ess-smart-underscore attempts to work with noweb-mode
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;; 22-May-2013 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Added more ggplot operators.
;; 21-May-2013 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Added math to ggplot's functions...
;; 21-May-2013 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Added hook to R-mode to make it behave a little better.
;; 15-May-2013 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Fixed ess-smart-underscore to work in an inferior R process.
;; 15-May-2013 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Added ggplot function prefixes.
;; 05-Nov-2012 Matthew L. Fidler
;; Last-Updated: Mon Apr 9 15:27:09 2012 (-0500) #137 (Matthew L. Fidler)
;; Better handling of noweb. I think it Came from Denis Haine and
;; Martin Maechler.
;; 22-Feb-2012 Matthew L. Fidler
;; Last-Updated: Wed Feb 22 20:27:04 2012 (-0600) #120 (Matthew L. Fidler)
;; Support unbalanced sexps.
;; 02-Feb-2012 Matthew L. Fidler
;; Last-Updated: Thu Feb 2 21:06:52 2012 (-0600) #117 (Matthew L. Fidler)
;; Took out auto-installing. Most package managers don't want you
;; to do this.
;; 03-Aug-2011 Matthew L. Fidler
;; Last-Updated: Wed Aug 3 15:05:15 2011 (-0500) #112 (Matthew L. Fidler)
;; Bug fix for parenthetical statement
;; 20-Jul-2011 Matthew L. Fidler
;; Last-Updated: Wed Jul 20 15:20:10 2011 (-0500) #101 (Matthew L. Fidler)
;; Changed to allow underscore instead of assign when inside a
;; parenthetical statement.
;; 15-Jul-2011 Matthew L. Fidler
;; Last-Updated: Fri Jul 15 11:34:52 2011 (-0500) #90 (Matthew L. Fidler)
;; Bug fix for d[d$CMT == 2,"DV"] _ to produce d[d$CMT == 2,"DV"] <-
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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, 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; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'ess)
(defcustom ess-S-underscore-after-$ t
"Should underscore produce an underscore if it is an element of a list/data structure?
Used by \\[ess-smart-underscore]."
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-after-defined t
"Should underscore produce an underscore if it is after a variable has been defined?
Used by \\[ess-smart-underscore]."
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-after-<-or-= t
"Should underscore produce an underscore if it is after a \"<-\" or \"=\"?
Used by \\[ess-smart-underscore]."
:group 'ess-S
:type 'boolean)
(defcustom ess-S-space-underscore-is-assignment t
"Should underscore produce `ess-S-assign' when a space is right before the cursor.
Used by \\[ess-smart-underscore]."
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-when-inside-paren t
"Should an underscore be produced instead of `ess-S-assign' when inside a parenthetical expression?"
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-when-inside-unbalanced-parenthesis t
"Should an underscore be produced instead of `ess-S-assign' when inside an unbalanced parenthetical expression such as:
foo(bar_
This requires `ess-S-underscore-when-inside-paren' to be true.
"
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-when-preceeding-words
'(
"add"
"aes"
"annotation"
"calc"
"continuous"
"coord"
"coord"
"cut"
"discrete"
"element"
"expand"
"facet"
"geom"
"gg"
"group"
"guide"
"label"
"last"
"math"
"mean"
"mutate"
"position"
"scale"
"scale_color"
"scale_colour"
"scale_x"
"scale_y"
"stat"
"theme"
"trans"
"translate"
"translate_qplot"
"update"
"update_"
"update_geom"
)
"Things that should have underscores after them. "
:group 'ess-S
:type '(repeat
(string :tag "Word")))
(defcustom ess-S-underscore-when-variable-contains-underscores t
"Should an underscore be produced instead of `ess-S-assign' when variable already contains an underscore?"
:group 'ess-S
:type 'boolean)
(defcustom ess-S-underscore-when-last-character-is-a-space nil
"ESS produces an underscore only when the last character is not a space or a tab."
:group 'ess-S
:type 'boolean)
;;;###autoload
(defun ess-smarter-underscore ()
"Smart \"_\" key: insert `ess-S-assign', unless:
1. in string/comment
2. after a $ (like d$one_two) (toggle with `ess-S-underscore-after-$')
3. when the underscore is part of a variable definition previously defined.
(toggle with `ess-S-underscore-after-defined')
4. when the underscore is after a \"=\" or \"<-\" on the same line.
(toggle with `ess-S-underscore-after-<-or-=')
5. inside a parenthetical statement () or [].
(toggle with `ess-S-underscore-when-inside-paren')
6. At the beginning of a line.
7. In a variable that contains underscores already (for example foo_a)
(toggle with `ess-S-underscore-when-variable-contains-underscores')
8. The preceding character is not a tab/space
(toggle with `ess-S-underscore-when-last-character-is-a-space'. Not enabled by default.)
9. The preceding words/characters are in `ess-S-underscore-when-preceeding-words'
An exception to #4 is in the following situation:
a <- b |
pressing an underscore here would produce
a <- b <-
However when in the following situation
a <- b|
pressing an underscore would produce
a <- b_
This behavior can be toggled by `ess-S-space-underscore-is-assignment'
If the underscore key is pressed a second time, the assignment
operator is removed and replaced by the underscore. `ess-S-assign',
typically \" <- \", can be customized. In ESS modes other than R/S,
an underscore is always inserted. "
(interactive)
;;(insert (if (ess-inside-string-or-comment-p (point)) "_"
;;ess-S-assign))
;;(message "%s" (looking-back "_[^ \t\n]*?\\="))
(save-restriction
(ignore-errors
(when (and (eq major-mode 'inferior-ess-mode)
(> (point) (process-mark (get-buffer-process
(current-buffer)))))
(narrow-to-region (process-mark (get-process ess-local-process-name)) (point-max)))
(and ess-noweb-mode
(noweb-in-code-chunk)
(noweb-narrow-to-chunk)))
(if (or
(not (equal ess-language "S"))
(looking-back "^[ \t\n]*\\=")
(looking-back (regexp-opt ess-S-underscore-when-preceeding-words t))
(and ess-S-underscore-when-variable-contains-underscores
(looking-back "_[^ \t\n]*?\\="))
(and ess-S-underscore-when-last-character-is-a-space
(looking-back "[^ \t]\\="))
(ess-inside-string-or-comment-p (point))
;; Data
(and ess-S-underscore-after-$ (save-match-data (save-excursion (re-search-backward "\\([$]\\)[A-Za-z0-9.]+\\=" nil t))))
(and ess-S-underscore-after-<-or-=
(let ((ret (save-match-data (and (not (looking-back ess-S-assign))
(looking-back "\\(<-\\|\\<=\\>\\).*")))))
(if (and ret ess-S-space-underscore-is-assignment
(looking-back "[ \t]"))
(setq ret nil))
(symbol-value 'ret)))
;; Look for variable
(and ess-S-underscore-after-defined
(not (looking-back ess-S-assign)) ; Hack to fix bug
(save-match-data
(save-excursion
(let (word)
(when (looking-back "\\<[A-Za-z0-9.]+[ \t]*")
(setq word (match-string 0))
(setq ret
(or (re-search-backward (format "^[ \t]*%s_[A-Za-z0-9.]*[ \t]*\\(<-\\|=\\)" word) nil t)
(re-search-backward (format "->[ \t]*%s_[A-Za-z0-9.]*[ \t]*$" word) nil t)))
(symbol-value 'ret))))))
(and ess-S-underscore-when-inside-paren
(save-match-data
(save-excursion
(let ((pt (point))
ret)
(when (re-search-backward "\\((\\|\\[\\).*\\=" nil t)
(condition-case err
(progn
(forward-sexp)
(when (> (point) pt)
(setq ret t)))
(error
(when ess-S-underscore-when-inside-unbalanced-parenthesis
(setq ret 't)))))
(symbol-value 'ret))))))
(insert "_")
;; Else one keypress produces ess-S-assign; a second keypress will delete
;; ess-S-assign and instead insert _
;; Rather than trying to count a second _ keypress, just check whether
;; the current point is preceded by ess-S-assign.
(let ((assign-len (length ess-S-assign)))
(if (and
(>= (point) (+ assign-len (point-min))) ;check that we can move back
(looking-back ess-S-assign))
;; If we are currently looking at ess-S-assign, replace it with _
(progn
(replace-match "")
(insert "_"))
(delete-horizontal-space)
(insert ess-S-assign))))))
(define-key ess-mode-map (kbd "_") 'ess-smarter-underscore)
(defun ess-smart-underscore-add-inf ()
"Add to inferior mode."
(local-set-key (kbd "_") 'ess-smarter-underscore))
(add-hook 'ess-R-post-run-hook 'ess-smart-underscore-add-inf)
(add-hook 'R-mode-hook 'ess-smart-underscore-add-inf)
(provide 'ess-smart-underscore)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ess-smart-underscore.el ends here