diff options
| author | Vegard Øye <vegard_oye@hotmail.com> | 2011-11-26 18:27:27 +0100 |
|---|---|---|
| committer | Vegard Øye <vegard_oye@hotmail.com> | 2011-11-26 18:27:27 +0100 |
| commit | 076130d88d4c3f4aa8f9ee1ff9537cb79ea2dce1 (patch) | |
| tree | e2fe1dce355e99afd6b882960822b91d9abc364c /evil-types.el | |
| parent | 0b0a2b9f0400529124225b07d981d5d4499aecdc (diff) | |
Restructure the code
Merge evil-motions.el, evil-operators.el and evil-window.el into
evil-commands.el. Merge evil-insert.el, evil-visual.el and
evil-replace.el into evil-states.el. Merge evil-interactive.el and
evil-types.el into evil-types.el. Merge evil-compatibility.el and
evil-undo.el into evil-common.el. Move macros into evil-macros.el.
Diffstat (limited to 'evil-types.el')
| -rw-r--r-- | evil-types.el | 431 |
1 files changed, 74 insertions, 357 deletions
diff --git a/evil-types.el b/evil-types.el index ffe5d9b..d96928e 100644 --- a/evil-types.el +++ b/evil-types.el @@ -24,363 +24,7 @@ ;; `evil-define-type'. (require 'evil-common) - -(defun evil-type (object &optional default) - "Return the type of OBJECT, or DEFAULT if none." - (let (type) - (cond - ((overlayp object) - (setq type (overlay-get object :type))) - ((evil-range-p object) - (setq type (nth 2 object))) - ((listp object) - (setq type (plist-get object :type))) - ((commandp object) - (setq type (evil-get-command-property object :type))) - ((symbolp object) - (setq type (get object 'type)))) - (setq type (or type default)) - (and (evil-type-p type) type))) - -(defun evil-set-type (object type) - "Set the type of OBJECT to TYPE. -For example, (evil-set-type 'next-line 'line) -will make `line' the type of the `next-line' command." - (cond - ((overlayp object) - (overlay-put object :type type)) - ((evil-range-p object) - (evil-set-range-type object type)) - ((listp object) - (plist-put object :type type)) - ((commandp object) - (evil-set-command-property object :type type)) - ((symbolp object) - (put object 'type type))) - object) - -(defun evil-type-property (type prop) - "Return property PROP for TYPE." - (evil-get-property evil-type-properties type prop)) - -(defun evil-type-p (sym) - "Whether SYM is the name of a type." - (assq sym evil-type-properties)) - -(defun evil-range (beg end &optional type &rest properties) - "Return a list (BEG END [TYPE] PROPERTIES...). -BEG and END are buffer positions (numbers or markers), -TYPE is a type as per `evil-type-p', and PROPERTIES is -a property list." - (let ((beg (evil-normalize-position beg)) - (end (evil-normalize-position end))) - (when (and (numberp beg) (numberp end)) - (append (list (min beg end) (max beg end)) - (when (evil-type-p type) - (list type)) - properties)))) - -(defun evil-range-p (object) - "Whether OBJECT is a range." - (and (listp object) - (>= (length object) 2) - (numberp (nth 0 object)) - (numberp (nth 1 object)))) - -(defun evil-range-beginning (range) - "Return beginning of RANGE." - (when (evil-range-p range) - (let ((beg (evil-normalize-position (nth 0 range))) - (end (evil-normalize-position (nth 1 range)))) - (min beg end)))) - -(defun evil-range-end (range) - "Return end of RANGE." - (when (evil-range-p range) - (let ((beg (evil-normalize-position (nth 0 range))) - (end (evil-normalize-position (nth 1 range)))) - (max beg end)))) - -(defun evil-range-properties (range) - "Return properties of RANGE." - (when (evil-range-p range) - (if (evil-type range) - (nthcdr 3 range) - (nthcdr 2 range)))) - -(defun evil-copy-range (range) - "Return a copy of RANGE." - (copy-sequence range)) - -(defun evil-set-range (range &optional beg end type &rest properties) - "Set RANGE to have beginning BEG and end END. -The TYPE and additional PROPERTIES may also be specified. -If an argument is nil, it's not used; the previous value is retained. -See also `evil-set-range-beginning', `evil-set-range-end', -`evil-set-range-type' and `evil-set-range-properties'." - (when (evil-range-p range) - (let ((beg (or (evil-normalize-position beg) - (evil-range-beginning range))) - (end (or (evil-normalize-position end) - (evil-range-end range))) - (type (or type (evil-type range))) - (plist (evil-range-properties range))) - (evil-sort beg end) - (setq plist (evil-concat-plists plist properties)) - (evil-set-range-beginning range beg) - (evil-set-range-end range end) - (evil-set-range-type range type) - (evil-set-range-properties range plist) - range))) - -(defun evil-set-range-beginning (range beg &optional copy) - "Set RANGE's beginning to BEG. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (setcar range beg) - range) - -(defun evil-set-range-end (range end &optional copy) - "Set RANGE's end to END. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (setcar (cdr range) end) - range) - -(defun evil-set-range-type (range type &optional copy) - "Set RANGE's type to TYPE. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (if type - (setcdr (cdr range) - (cons type (evil-range-properties range))) - (setcdr (cdr range) (evil-range-properties range))) - range) - -(defun evil-set-range-properties (range properties &optional copy) - "Set RANGE's properties to PROPERTIES. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (if (evil-type range) - (setcdr (cdr (cdr range)) properties) - (setcdr (cdr range) properties)) - range) - -(defun evil-range-union (range1 range2 &optional type) - "Return the union of the ranges RANGE1 and RANGE2. -If the ranges have conflicting types, use RANGE1's type. -This can be overridden with TYPE." - (when (and (evil-range-p range1) - (evil-range-p range2)) - (evil-range (min (evil-range-beginning range1) - (evil-range-beginning range2)) - (max (evil-range-end range1) - (evil-range-end range2)) - (or type - (evil-type range1) - (evil-type range2))))) - -(defun evil-subrange-p (range1 range2) - "Whether RANGE1 is contained within RANGE2." - (and (evil-range-p range1) - (evil-range-p range2) - (<= (evil-range-beginning range2) - (evil-range-beginning range1)) - (>= (evil-range-end range2) - (evil-range-end range1)))) - -(defun evil-expand (beg end type &rest properties) - "Expand BEG and END as TYPE with PROPERTIES. -Returns a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply 'evil-transform - ;; don't expand if already expanded - (unless (plist-get properties :expanded) :expand) - beg end type properties)) - -(defun evil-contract (beg end type &rest properties) - "Contract BEG and END as TYPE with PROPERTIES. -Returns a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply 'evil-transform 'contract beg end type properties)) - -(defun evil-normalize (beg end type &rest properties) - "Normalize BEG and END as TYPE with PROPERTIES. -Returns a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply 'evil-transform 'normalize beg end type properties)) - -(defun evil-transform - (transform beg end type &rest properties) - "Apply TRANSFORM on BEG and END with PROPERTIES. -Returns a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list. If TRANSFORM is undefined, -return positions unchanged." - (let* ((type (or type (evil-type properties))) - (transform (when (and type transform) - (evil-type-property type transform)))) - (if transform - (apply transform beg end properties) - (apply 'evil-range beg end type properties)))) - -(defun evil-describe (beg end type &rest properties) - "Return description of BEG and END with PROPERTIES. -If no description is available, return the empty string." - (let* ((type (or type (evil-type properties))) - (properties (plist-put properties :type type)) - (describe (evil-type-property type :string))) - (or (when describe - (apply describe beg end properties)) - ""))) - -(defun evil-expand-range (range &optional copy) - "Expand RANGE according to its type. -Return a new range if COPY is non-nil." - (when copy - (setq range (evil-copy-range range))) - (unless (plist-get (evil-range-properties range) :expanded) - (setq range (evil-transform-range :expand range))) - range) - -(defun evil-contract-range (range &optional copy) - "Contract RANGE according to its type. -Return a new range if COPY is non-nil." - (evil-transform-range 'contract range copy)) - -(defun evil-normalize-range (range &optional copy) - "Normalize RANGE according to its type. -Return a new range if COPY is non-nil." - (evil-transform-range 'normalize range copy)) - -(defun evil-transform-range (transform range &optional copy) - "Apply TRANSFORM to RANGE according to its type. -Return a new range if COPY is non-nil." - (when copy - (setq range (evil-copy-range range))) - (when (evil-type range) - (apply 'evil-set-range range - (apply 'evil-transform transform range))) - range) - -(defun evil-describe-range (range) - "Return description of RANGE. -If no description is available, return the empty string." - (apply 'evil-describe range)) - -(defmacro evil-define-type (type doc &rest body) - "Define type TYPE. -DOC is a general description and shows up in all docstrings. -It is followed by a list of keywords and functions: - -:expand FUNC Expansion function. This function should accept - two positions in the current buffer, BEG and END, - and return a pair of expanded buffer positions. -:contract FUNC The opposite of :expand, optional. -:one-to-one BOOL Whether expansion is one-to-one. This means that - :expand followed by :contract always returns the - original range. -:normalize FUNC Normalization function, optional. This function should - accept two unexpanded positions and adjust them before - expansion. May be used to deal with buffer boundaries. -:string FUNC Description function. This takes two buffer positions - and returns a human-readable string, for example, - \"2 lines\". - -Further keywords and functions may be specified. These are assumed to -be transformations on buffer positions, like :expand and :contract. - -\(fn TYPE DOC [[KEY FUNC]...])" - (declare (indent defun) - (debug (&define name - [&optional stringp] - [&rest [keywordp function-form]]))) - (let (args defun-forms func key name plist string sym val) - ;; standard values - (setq plist (plist-put plist :one-to-one t)) - ;; keywords - (while (keywordp (car-safe body)) - (setq key (pop body) - val (pop body)) - (if (plist-member plist key) ; not a function - (setq plist (plist-put plist key val)) - (setq func val - sym (intern (replace-regexp-in-string - "^:" "" (symbol-name key))) - name (intern (format "evil-%s-%s" type sym)) - args (car (cdr-safe func)) - string (car (cdr (cdr-safe func))) - string (if (stringp string) - (format "%s\n\n" string) "") - plist (plist-put plist key `',name)) - (add-to-list - 'defun-forms - (cond - ((eq key :string) - `(defun ,name (beg end &rest properties) - ,(format "Return size of %s from BEG to END \ -with PROPERTIES.\n\n%s%s" type string doc) - (let ((beg (evil-normalize-position beg)) - (end (evil-normalize-position end)) - (type ',type) - plist range) - (when (and beg end) - (save-excursion - (evil-sort beg end) - (unless (plist-get properties :expanded) - (setq range (apply 'evil-expand - beg end type properties) - beg (evil-range-beginning range) - end (evil-range-end range) - type (evil-type range type) - plist (evil-range-properties range)) - (setq properties - (evil-concat-plists properties plist))) - (or (apply ',func beg end - (when ,(> (length args) 2) - properties)) - "")))))) - (t - `(defun ,name (beg end &rest properties) - ,(format "Perform %s transformation on %s from BEG to END \ -with PROPERTIES.\n\n%s%s" sym type string doc) - (let ((beg (evil-normalize-position beg)) - (end (evil-normalize-position end)) - (type ',type) - plist range) - (when (and beg end) - (save-excursion - (evil-sort beg end) - (when (memq ,key '(:expand :contract)) - (setq properties - (plist-put properties - :expanded - ,(eq key :expand)))) - (setq range (or (apply ',func beg end - (when ,(> (length args) 2) - properties)) - (apply 'evil-range - beg end type properties)) - beg (evil-range-beginning range) - end (evil-range-end range) - type (evil-type range type) - plist (evil-range-properties range)) - (setq properties - (evil-concat-plists properties plist)) - (apply 'evil-range beg end type properties))))))) - t))) - ;; :one-to-one requires both or neither of :expand and :contract - (when (plist-get plist :expand) - (setq plist (plist-put plist :one-to-one - (and (plist-get plist :contract) - (plist-get plist :one-to-one))))) - `(progn - (evil-put-property 'evil-type-properties ',type ,@plist) - ,@defun-forms - ',type))) +(require 'evil-macros) ;;; Type definitions @@ -546,6 +190,79 @@ and `lower-right'." :corner corner)) (apply 'evil-range beg end properties)))) +;;; Standard interactive codes + +(evil-define-interactive-code "*" + "Signal error if the buffer is read-only." + (when buffer-read-only + (signal 'buffer-read-only nil))) + +(evil-define-interactive-code "b" (prompt) + "Name of existing buffer." + (list (read-buffer prompt (current-buffer) t))) + +(evil-define-interactive-code "c" + "Read character." + (list (read-char))) + +(evil-define-interactive-code "p" + "Prefix argument converted to number." + (list (prefix-numeric-value current-prefix-arg))) + +(evil-define-interactive-code "P" + "Prefix argument in raw form." + (list current-prefix-arg)) + +;;; Custom interactive codes + +(evil-define-interactive-code "<c>" + "Count." + (list (when current-prefix-arg + (prefix-numeric-value + current-prefix-arg)))) + +(evil-define-interactive-code "<r>" + "Untyped motion range (BEG END)." + (evil-operator-range)) + +(evil-define-interactive-code "<R>" + "Typed motion range (BEG END TYPE)." + (evil-operator-range t)) + +(evil-define-interactive-code "<x>" + "Current register." + (list evil-this-register)) + +(evil-define-interactive-code "<y>" + "Current yank-handler." + (list (evil-yank-handler))) + +(evil-define-interactive-code "<f>" + :ex-arg file + (list (and (evil-ex-state-p) (evil-ex-file-arg)))) + +(evil-define-interactive-code "<b>" + :ex-arg buffer + (list (and (evil-ex-state-p) evil-ex-current-arg))) + +(evil-define-interactive-code "<a>" + :ex-arg t + (list (and (evil-ex-state-p) evil-ex-current-arg))) + +(evil-define-interactive-code "<!>" + :ex-force t + (list (and (evil-ex-state-p) evil-ex-current-cmd-force))) + +(evil-define-interactive-code "<sym>" + :ex-arg sym + (list (and (evil-ex-state-p) + evil-ex-current-arg + (intern evil-ex-current-arg)))) + +(evil-define-interactive-code "<s/>" + :ex-arg substitution + (list (and (evil-ex-state-p) evil-ex-current-arg))) + (provide 'evil-types) ;;; evil-types.el ends here |
