[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] 10/16: Support Org mode with list-wise +/- and sexp selection
From: |
Leo Liu |
Subject: |
[elpa] 10/16: Support Org mode with list-wise +/- and sexp selection |
Date: |
Tue, 22 Apr 2014 00:33:39 +0000 |
leoliu pushed a commit to branch master
in repository elpa.
commit 34559f7368b61ab28c268a36bdb7ef0a35f4ea81
Author: Leo Liu <address@hidden>
Date: Mon Apr 21 07:59:28 2014 +0800
Support Org mode with list-wise +/- and sexp selection
Make easy-kill-thing-handler generic for dispatching.
---
README.rst | 6 ++-
easy-kill.el | 122 ++++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 93 insertions(+), 35 deletions(-)
diff --git a/README.rst b/README.rst
index b4d4625..ecbc28b 100644
--- a/README.rst
+++ b/README.rst
@@ -51,7 +51,8 @@ for ``list`` or ``sexp``, list-wise.
``list-wise`` expanding/shrinking work well in lispy modes (elisp,
Common Lisp, Scheme, Clojure etc.), smie-based modes (Prolog, SML,
-Modula2, Shell, Ruby, Octave, CSS, SQL etc.), Nxml mode and Js2 mode.
+Modula2, Shell, Ruby, Octave, CSS, SQL etc.), Org mode, Nxml mode and
+Js2 mode.
To copy the enclosing list in lispy modes, I used to do a lot of
``C-M-u C-M-SPC M-w``. Now the key sequence is replaced by ``M-w l``
@@ -95,8 +96,9 @@ NEWS
#. Key ``?`` in ``easy-kill`` or ``easy-mark`` prints help info.
#. ``M-w l`` can select the enclosing string.
#. ``easy-mark`` learns exchanging point & mark.
-#. ``0`` now sets the selection to its initial size before any
+#. Key ``0`` now sets the selection to its initial size before any
expansion.
+#. ``M-w l``, ``M-w s`` and list-wise ``+/-`` now work in Org mode.
0.9.2
+++++
diff --git a/easy-kill.el b/easy-kill.el
index 67ac1a0..2fab50c 100644
--- a/easy-kill.el
+++ b/easy-kill.el
@@ -141,6 +141,12 @@ Do nothing if `easy-kill-inhibit-message' is non-nil."
(`right (substring s 0 (string-match-p (concat wchars "\\'") s)))
(_ (easy-kill-trim (easy-kill-trim s 'left) 'right)))))
+(defun easy-kill-mode-sname (m)
+ (cl-check-type m (and (or symbol string) (not boolean)))
+ (cl-etypecase m
+ (symbol (easy-kill-mode-sname (symbol-name m)))
+ (string (substring m 0 (string-match-p "\\(?:-minor\\)?-mode\\'" m)))))
+
(defun easy-kill-fboundp (name)
"Like `fboundp' but NAME can be string or symbol.
The value is the function's symbol if non-nil."
@@ -233,6 +239,7 @@ Use `setf' to change property value."
(`buffer '(overlay-buffer easy-kill-candidate))
(`properties '(append (list 'start (easy-kill-get start))
(list 'end (easy-kill-get end))
+ (list 'buffer (easy-kill-get buffer))
(overlay-properties easy-kill-candidate)))
(_ `(overlay-get easy-kill-candidate ',prop))))
@@ -374,17 +381,37 @@ expansion."
(interactive)
(easy-kill-thing nil '-))
+(defun easy-kill-thing-handler (base mode)
+ "Get the handler for MODE or nil if none is defined.
+For example, if BASE is \"easy-kill-on-list\" and MODE is
+nxml-mode `nxml:easy-kill-on-list', `easy-kill-on-list:nxml' are
+checked in order. The former is never defined in this package and
+is safe for users to customise. If neither is defined continue
+checking on the parent mode. Finally `easy-kill-on-list' is
+checked."
+ (or (and mode (or (easy-kill-fboundp
+ (concat (easy-kill-mode-sname mode) ":" base))
+ (easy-kill-fboundp
+ (concat base ":" (easy-kill-mode-sname mode)))))
+ (let ((parent (get mode 'derived-mode-parent)))
+ (and parent (easy-kill-thing-handler base parent)))
+ (easy-kill-fboundp base)))
+
(defun easy-kill-bounds-of-thing-at-point (thing)
"Easy Kill wrapper for `bounds-of-thing-at-point'."
- (pcase (get thing 'easy-kill-bounds-of-thing-at-point)
- (`nil (bounds-of-thing-at-point thing))
- (fn (funcall fn))))
+ (pcase (easy-kill-thing-handler
+ (format "easy-kill-bounds-of-%s-at-point" thing)
+ major-mode)
+ ((and (pred functionp) fn) (funcall fn))
+ (_ (bounds-of-thing-at-point thing))))
(defun easy-kill-thing-forward-1 (thing &optional n)
"Easy Kill wrapper for `forward-thing'."
- (pcase (get thing 'easy-kill-forward-op)
- (`nil (forward-thing thing n))
- (fn (funcall fn (or n 1)))))
+ (pcase (easy-kill-thing-handler
+ (format "easy-kill-thing-forward-%s" thing)
+ major-mode)
+ ((and (pred functionp) fn) (funcall fn n))
+ (_ (forward-thing thing n))))
;; Helper for `easy-kill-thing'.
(defun easy-kill-thing-forward (n)
@@ -412,25 +439,6 @@ expansion."
(easy-kill-adjust-candidate thing start end)
t)))))
-(defun easy-kill-thing-handler (thing mode)
- "Get the handler for THING or nil if none is defined.
-For example, if THING is list and MODE is nxml-mode
-`nxml:easy-kill-on-list', `easy-kill-on-list:nxml' are checked in
-order. The former is never defined in this package and is safe
-for users to customise. If neither is defined continue checking
-on the parent mode. Finally `easy-kill-on-list' is checked."
- (cl-labels ((sname (m) (cl-etypecase m
- (symbol (sname (symbol-name m)))
- (string (substring m 0 (string-match-p
- "\\(?:-minor\\)?-mode\\'"
m))))))
- (let ((parent (get mode 'derived-mode-parent)))
- (or (and mode (or (easy-kill-fboundp
- (format "%s:easy-kill-on-%s" (sname mode) thing))
- (easy-kill-fboundp
- (format "easy-kill-on-%s:%s" thing (sname mode)))))
- (and parent (easy-kill-thing-handler thing parent))
- (easy-kill-fboundp (format "easy-kill-on-%s" thing))))))
-
(defun easy-kill-thing (&optional thing n inhibit-handler)
;; N can be -, + and digits
(interactive
@@ -441,7 +449,8 @@ on the parent mode. Finally `easy-kill-on-list' is checked."
(let* ((thing (or thing (easy-kill-get thing)))
(n (or n 1))
(handler (and (not inhibit-handler)
- (easy-kill-thing-handler thing major-mode))))
+ (easy-kill-thing-handler (format "easy-kill-on-%s"
thing)
+ major-mode))))
(when easy-kill-mark
(goto-char (easy-kill-get origin)))
(cond
@@ -632,16 +641,13 @@ inspected."
;;; `defun'
;; Work around http://debbugs.gnu.org/17247
-(put 'defun 'easy-kill-forward-op (lambda (n)
- (if (cl-minusp n)
- (beginning-of-defun (- n))
- (end-of-defun n))))
+(defun easy-kill-thing-forward-defun (&optional n)
+ (pcase (or n 1)
+ ((pred cl-minusp) (beginning-of-defun (- n)))
+ (_ (end-of-defun n))))
;;; Handler for `sexp' and `list'.
-(put 'list 'easy-kill-bounds-of-thing-at-point
- #'easy-kill-bounds-of-list-at-point)
-
(defun easy-kill-bounds-of-list-at-point ()
(let ((bos (and (nth 3 (syntax-ppss)) ;bounds of string
(save-excursion
@@ -729,6 +735,56 @@ inspected."
(easy-kill-thing 'sexp n t)
(setf (easy-kill-get thing) 'list))))))
+;;; org support for list-wise +/-
+
+(defun easy-kill-bounds-of-list-at-point:org ()
+ (eval-and-compile (require 'org-element))
+ (let ((x (org-element-at-point)))
+ (cons (org-element-property :begin x)
+ (org-element-property :end x))))
+
+(defun easy-kill-bounds-of-sexp-at-point:org ()
+ (pcase (list (point) (easy-kill-bounds-of-list-at-point:org))
+ (`(,beg (,beg . ,end))
+ (cons beg end))
+ (_ (bounds-of-thing-at-point 'sexp))))
+
+(defun easy-kill-thing-forward-list:org (&optional n)
+ (pcase (or n 1)
+ (`0 nil)
+ (_ (dotimes (_ (abs n))
+ (condition-case nil
+ (if (cl-minusp n)
+ (org-backward-element)
+ (org-forward-element))
+ (error (pcase (easy-kill-bounds-of-thing-at-point 'list)
+ (`(,beg . ,end)
+ (goto-char (if (cl-minusp n) beg end))))))))))
+
+(defun easy-kill-org-up-element (&optional n)
+ ;; Make `org-up-element' more like `up-list'.
+ (pcase (or n 1)
+ (`0 nil)
+ (_ (ignore-errors (dotimes (_ (abs n)) (org-up-element)))
+ (when (cl-plusp n)
+ (goto-char (cdr (easy-kill-bounds-of-thing-at-point 'list)))))))
+
+(defun easy-kill-on-list:org (n)
+ (pcase n
+ ((or `+ `-)
+ (pcase (let ((up-list-fn #'easy-kill-org-up-element))
+ (easy-kill-bounds-of-list n))
+ (`(,beg . ,end) (easy-kill-adjust-candidate 'list beg end))))
+ (_ (easy-kill-thing 'list n t)))
+ (pcase (save-excursion
+ (goto-char (easy-kill-get start))
+ (org-element-type (org-element-at-point)))
+ (`nil nil)
+ (type (setf (easy-kill-get describe-thing)
+ (lambda ()
+ (format "%s (%s)" (easy-kill-get thing) type)))
+ (easy-kill-echo "%s" type))))
+
;;; js2 support for list-wise +/-
(defun easy-kill-find-js2-node (beg end &optional inner)
- [elpa] 07/16: Fix #15: Make `M-w l' in strings save to clipboard, (continued)
- [elpa] 07/16: Fix #15: Make `M-w l' in strings save to clipboard, Leo Liu, 2014/04/21
- [elpa] 04/16: Improve last change for easy-kill-thing-forward, Leo Liu, 2014/04/21
- [elpa] 09/16: Make digit key 0 shrink selection to its initial size, Leo Liu, 2014/04/21
- [elpa] 14/16: Fix easy-kill-org-up-element, Leo Liu, 2014/04/21
- [elpa] 08/16: Add wrappers for thingatpt.el for better code organisation, Leo Liu, 2014/04/21
- [elpa] 16/16: Merge branch 'master' of https://github.com/leoliu/easy-kill, Leo Liu, 2014/04/21
- [elpa] 13/16: Some tests and bug fixes for org, Leo Liu, 2014/04/21
- [elpa] 12/16: Localize two global states using overlay properties, Leo Liu, 2014/04/21
- [elpa] 11/16: Add tests and enable travis-ci, Leo Liu, 2014/04/21
- [elpa] 15/16: Fix emacs-snapshot in travis-ci and use svg badge, Leo Liu, 2014/04/21
- [elpa] 10/16: Support Org mode with list-wise +/- and sexp selection,
Leo Liu <=