[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] 04/77: Use overlay for storing kill candidate and change +/-
From: |
Leo Liu |
Subject: |
[elpa] 04/77: Use overlay for storing kill candidate and change +/- |
Date: |
Sat, 05 Apr 2014 04:08:10 +0000 |
leoliu pushed a commit to branch master
in repository elpa.
commit b42b1e4956baffa1cc4a417ec68beb56f4cb0f22
Author: Leo Liu <address@hidden>
Date: Sun Oct 6 10:56:58 2013 +0800
Use overlay for storing kill candidate and change +/-
which also fixes breakage in emacs trunk, which has implemented
universal-argument using set-temporary-overlay-map.
---
easy-kill.el | 182 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 90 insertions(+), 92 deletions(-)
diff --git a/easy-kill.el b/easy-kill.el
index 1d666f1..dfd1456 100644
--- a/easy-kill.el
+++ b/easy-kill.el
@@ -3,7 +3,7 @@
;; Copyright (C) 2013 Leo Liu
;; Author: Leo Liu <address@hidden>
-;; Version: 0.5.0
+;; Version: 0.6.0
;; Keywords: convenience
;; Created: 2013-08-12
@@ -22,7 +22,8 @@
;;; Commentary:
-;; Kill things easily in emacs.
+;; `easy-kill' aims to be a drop-in replacement for `kill-ring-save'.
+;;
;; To use: (global-set-key "\M-w" 'easy-kill)
;;; Code:
@@ -35,11 +36,16 @@
(?s . sexp)
(?l . list)
(?f . filename)
- (?d . defun))
+ (?d . defun)
+ (?b . buffer-file-name))
"A list of (Key . THING)."
:type '(repeat (cons character symbol))
:group 'killing)
+(defface easy-kill-face '((t (:inherit 'secondary-selection)))
+ "Faced used to highlight kill candidate."
+ :group 'killing)
+
(defun easy-kill-message-nolog (format-string &rest args)
"Same as `message' except not writing to *Messages* buffer."
(let (message-log-max)
@@ -47,17 +53,18 @@
(defvar easy-kill-candidate nil)
-(defun easy-kill-remember (str)
- (when str
- (setq easy-kill-candidate str)
- ;; Immediately put it in clipboard for other applications.
- (and interprogram-cut-function
- (funcall interprogram-cut-function str))
- (easy-kill-message-nolog "%s" str)))
+(defun easy-kill-candidate ()
+ (when (overlayp easy-kill-candidate)
+ (if (eq (overlay-start easy-kill-candidate)
+ (overlay-end easy-kill-candidate))
+ (overlay-get easy-kill-candidate 'candidate)
+ (buffer-substring (overlay-start easy-kill-candidate)
+ (overlay-end easy-kill-candidate)))))
(defun easy-kill-map ()
(let ((map (make-sparse-keymap)))
- (define-key map "-" 'easy-kill-negative-argument)
+ (define-key map "-" 'easy-kill-backward)
+ (define-key map "+" 'easy-kill-forward)
(mapc (lambda (d)
(define-key map (number-to-string d) 'easy-kill-digit-argument))
(number-sequence 0 9))
@@ -67,87 +74,56 @@
(mapcar 'car easy-kill-alist))
map))
-;;; `digit-argument' is incompatible with `set-temporary-overlay-map'
-;;; becauses the former overrides the latter's keymap.
-
-(defun easy-kill-digit-argument (arg)
- (interactive "P")
- (digit-argument arg)
- ;; Counter the effect of (save&set-overriding-map universal-argument-map).
- (restore-overriding-map))
-
-(defun easy-kill-negative-argument (arg)
- (interactive "P")
- (negative-argument arg)
- (restore-overriding-map))
-
-(defun easy-kill-bounds (thing &optional n)
- "Like `bounds-of-thing-at-point' but allow upto N things.
-Return nil if no THING at point."
- (or n (setq n 1))
- (let* ((bounds (bounds-of-thing-at-point thing))
- (beg (car bounds))
- (end (cdr bounds))
- (count 0)
- (step (if (minusp n) -1 1)))
- (when bounds
+(defun easy-kill-forward (n)
+ (interactive "p")
+ (let ((direction (if (minusp n) -1 +1))
+ (thing (overlay-get easy-kill-candidate 'thing))
+ (start (overlay-start easy-kill-candidate))
+ (end (overlay-end easy-kill-candidate)))
+ (when thing
(save-excursion
- (if (minusp n)
- (goto-char end)
- (goto-char beg))
- (while (ignore-errors (forward-thing thing step)
- (incf count)
- (if (< count (abs n)) t nil)))
- ;; Don't update if point is located between BEG and END.
- (unless (and (<= (point) end) (<= beg (point)))
- (if (minusp n)
- (setq beg (point))
- (setq end (point)))))
- (cons beg end))))
-
-(defun easy-kill-select (&optional n)
+ (goto-char end)
+ (with-demoted-errors
+ (dotimes (_ (abs n))
+ (forward-thing thing direction)
+ (when (<= (point) start)
+ (forward-thing thing 1)
+ (return))))
+ (when (/= end (point))
+ (move-overlay easy-kill-candidate start (point))
+ t)))))
+
+(defun easy-kill-backward (n)
+ (interactive "p")
+ (easy-kill-forward (- n)))
+
+(defun easy-kill-thing (thing &optional n)
+ ;; Return non-nil if succeed
+ (when (and thing
+ (let ((n (or n 1)))
+ (cond
+ ((intern-soft (format "easy-kill-on-%s" thing))
+ (funcall (intern-soft (format "easy-kill-on-%s" thing)) n))
+ ((eq thing (overlay-get easy-kill-candidate 'thing))
+ (easy-kill-forward n))
+ (t (let ((bounds (bounds-of-thing-at-point thing)))
+ (when bounds
+ (move-overlay easy-kill-candidate (car bounds) (cdr
bounds))
+ (overlay-put easy-kill-candidate 'thing thing)
+ (easy-kill-forward (1- n))
+ t))))))
+ ;; Immediately put it in clipboard for other applications.
+ (and interprogram-cut-function
+ (funcall interprogram-cut-function (or (easy-kill-candidate) "")))
+ t))
+
+(defun easy-kill-select (n)
(interactive "p")
(let ((thing (cdr (assoc (car (last (listify-key-sequence
(single-key-description
last-command-event))))
- easy-kill-alist)))
- bounds)
- (if (not (setq bounds (easy-kill-bounds thing n)))
- (easy-kill-message-nolog "No `%s' at point." thing)
- (easy-kill-remember (buffer-substring (car bounds) (cdr bounds))))))
-
-(defun easy-kill-url-at-point ()
- "Get the url at point.
-It inspects char properties `help-echo', `shr-url' and
-`w3m-href-anchor'."
- (if (bounds-of-thing-at-point 'url)
- (thing-at-point 'url)
- (loop for prop in '(help-echo shr-url w3m-href-anchor)
- for data = (get-char-property-and-overlay (point) prop)
- for text = (car data)
- for overlay = (cdr data)
- when (and (stringp text) (with-temp-buffer
- (insert text)
- (easy-kill-url-at-point)))
- return it
- when (and overlay (overlay-get overlay prop))
- when (and (stringp it) (with-temp-buffer
- (insert it)
- (easy-kill-url-at-point)))
- return it)))
-
-(defun easy-kill-guess (n)
- (or (and (use-region-p)
- (buffer-substring (region-beginning) (region-end)))
- (easy-kill-url-at-point)
- (save-restriction
- ;; Note (bounds-of-thing-at-point 'email) takes time
- ;; proportional to buffer size, so narrow buffer for
- ;; efficiency.
- (narrow-to-region (line-beginning-position (- (abs n)))
- (line-end-position (abs n)))
- (loop for thing in '(email line)
- when (easy-kill-bounds thing n)
- return (buffer-substring (car it) (cdr it))))))
+ easy-kill-alist))))
+ (or (easy-kill-thing thing n)
+ (easy-kill-message-nolog "No `%s' at point." thing))))
(defun easy-kill-activate-keymap ()
(let ((map (easy-kill-map)))
@@ -171,16 +147,38 @@ It inspects char properties `help-echo', `shr-url' and
;; `easy-kill-remember' already did the work.
(let ((interprogram-cut-function nil)
(interprogram-paste-function nil))
- (kill-new easy-kill-candidate))
+ (kill-ring-save (overlay-start easy-kill-candidate)
+ (overlay-end easy-kill-candidate)))
+ (delete-overlay easy-kill-candidate)
(setq easy-kill-candidate nil)
nil)))))))
;;;###autoload
-(defun easy-kill (&optional n)
- (interactive "p")
- (easy-kill-remember (easy-kill-guess n))
+(defun easy-kill ()
+ (interactive)
+ (setq easy-kill-candidate (let ((o (make-overlay (point) (point))))
+ (overlay-put o 'face 'easy-kill-face)
+ o))
(setq deactivate-mark t)
+ (dolist (thing (if (use-region-p)
+ '(region url email line)
+ '(url email line)))
+ (when (easy-kill-thing thing)
+ (return)))
(easy-kill-activate-keymap))
+;;; Extended things
+
+(put 'region 'bounds-of-thing-at-point
+ (lambda () (cons (region-beginning) (region-end))))
+
+(defun easy-kill-on-buffer-file-name (_n)
+ (when buffer-file-name
+ (move-overlay easy-kill-candidate (point) (point))
+ (overlay-put easy-kill-candidate 'candidate buffer-file-name)
+ (overlay-put easy-kill-candidate 'thing 'buffer-file-name)
+ (easy-kill-message-nolog "%s" buffer-file-name)
+ t))
+
(provide 'easy-kill)
;;; easy-kill.el ends here
- [elpa] branch master updated (769f2f2 -> 0a73626), Leo Liu, 2014/04/05
- [elpa] 03/77: Fix error: wrong-type-argument number-or-marker-p nil, Leo Liu, 2014/04/05
- [elpa] 02/77: Fix error when interprogram-cut-function unset, Leo Liu, 2014/04/05
- [elpa] 05/77: Call interprogram-cut-function in easy-kill-forward, Leo Liu, 2014/04/05
- [elpa] 01/77: Initial commit, Leo Liu, 2014/04/05
- [elpa] 07/77: Rename easy-kill-forward/backward to easy-kill-enlarge/shrink, Leo Liu, 2014/04/05
- [elpa] 08/77: Give overlay by easy-kill-candidate higher priority, Leo Liu, 2014/04/05
- [elpa] 06/77: Various bug fixes and improvements, Leo Liu, 2014/04/05
- [elpa] 09/77: Restore the ability to inspect char properties for URLs, Leo Liu, 2014/04/05
- [elpa] 04/77: Use overlay for storing kill candidate and change +/-,
Leo Liu <=
- [elpa] 11/77: Minor tweaks to easy-kill-on-url, Leo Liu, 2014/04/05
- [elpa] 12/77: Tweak the definition of thing `region', Leo Liu, 2014/04/05
- [elpa] 13/77: New command easy-kill-region to kill current selection, Leo Liu, 2014/04/05
- [elpa] 10/77: New function easy-kill-adjust-candidate and doc fix, Leo Liu, 2014/04/05
- [elpa] 16/77: Make function easy-kill-candidate always return string, Leo Liu, 2014/04/05
- [elpa] 17/77: Fix error: (args-out-of-range 1009 1035), Leo Liu, 2014/04/05
- [elpa] 15/77: Some string and comment fixes, Leo Liu, 2014/04/05
- [elpa] 23/77: Use parse-partial-sexp in easy-kill-bounds-of-list, Leo Liu, 2014/04/05
- [elpa] 20/77: Replace `enlarge' with `expand' in strings and comments, Leo Liu, 2014/04/05
- [elpa] 19/77: Add lispy treatment for +/- on list and sexp, Leo Liu, 2014/04/05