Repository navigation
Expand file tree
/
Copy pathevil-text-object-python.el
More file actions
132 lines (112 loc) · 5.11 KB
/
Copy pathevil-text-object-python.el
File metadata and controls
132 lines (112 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;;; evil-text-object-python.el --- Python specific evil text objects -*- lexical-binding: t; -*-
;; Author: Wouter Bolsterlee <wouter@bolsterl.ee>
;; Version: 1.1.0
;; Package-Requires: ((emacs "25") (evil "1.2.14") (dash "2.16.0"))
;; Keywords: convenience languages tools
;; URL: https://github.com/wbolster/evil-text-object-python
;;
;; This file is not part of GNU Emacs.
;;; License:
;; Licensed under the same terms as Emacs.
;;; Commentary:
;; This package provides text objects for Python statements for use
;; with evil-mode. See the README for more details.
;;; Code:
(require 'dash)
(require 'evil)
(require 'python)
(defgroup evil-text-object-python nil
"Evil text objects for Python"
:prefix "evil-text-object-python-"
:group 'evil)
(defcustom evil-text-object-python-statement-key "l"
"Key to use for a Python statement in the text object maps."
:type 'string
:group 'evil-text-object-python)
(defcustom evil-text-object-python-function-key "f"
"Key to use for a Python function in the text object maps."
:type 'string
:group 'evil-text-object-python)
(defun evil-text-object-python--detect-key(containing-map child)
"Detect which key in CONTAINING-MAP maps to CHILD."
;; Note: this only uses the single match.
(key-description (car (where-is-internal child containing-map))))
(defun evil-text-object-python--define-key (key text-objects-map text-object)
"Bind KEY in TEXT-OBJECTS-MAP to TEXT-OBJECT."
;; Note: this only defines keys in local keymaps and does not change
;; the global text object maps. First detect the prefixes used in
;; the global maps (defaults are "i" for the inner text objects map,
;; and "a" for the outer text objects map), and use the same prefix
;; for the local bindings.
(define-key evil-operator-state-local-map
(kbd (format "%s %s" (evil-text-object-python--detect-key evil-operator-state-map text-objects-map) key))
text-object)
(define-key evil-visual-state-local-map
(kbd (format "%s %s" (evil-text-object-python--detect-key evil-visual-state-map text-objects-map) key))
text-object))
(defun evil-text-object-python--make-text-object (count type)
"Helper to make text object for COUNT Python statements of TYPE."
(let ((beg (save-excursion
(python-nav-beginning-of-statement)
(when (or (eq this-command 'evil-delete) (eq type 'line))
(beginning-of-line))
(point)))
(end (save-excursion
(--dotimes (1- count)
(python-nav-forward-statement))
(python-nav-end-of-statement)
(when (eq type 'line)
(forward-line))
(point))))
(evil-range beg end)))
(defun evil-text-object-python--make-func-text-object (count type)
"Helper to make text object for COUNT Python statements of TYPE."
(let ((beg (save-excursion
(python-nav-backward-defun)
(when (or (eq this-command 'evil-delete) (eq type 'line))
(beginning-of-line))
(point)))
(end (save-excursion
(--dotimes (1- count)
(python-nav-forward-defun))
(python-nav-end-of-defun)
(when (eq type 'line)
(forward-line))
(point))))
(evil-range beg end)))
;;;###autoload (autoload 'evil-text-object-python-inner-statement "evil-text-object-python" nil t)
(evil-define-text-object evil-text-object-python-inner-statement (count &optional beg end type)
"Inner text object for the Python statement under point."
(evil-text-object-python--make-text-object count type))
;;;###autoload (autoload 'evil-text-object-python-outer-statement "evil-text-object-python" nil t)
(evil-define-text-object evil-text-object-python-outer-statement (count &optional beg end type)
"Outer text object for the Python statement under point."
:type line
(evil-text-object-python--make-text-object count type))
;;;###autoload (autoload 'evil-text-object-python-function "evil-text-object-python" nil t)
(evil-define-text-object evil-text-object-python-function (count &optional beg end type)
"Inner text object for the Python statement under point."
(evil-text-object-python--make-func-text-object count type))
;;;###autoload
(defun evil-text-object-python-add-bindings ()
"Add text object key bindings.
This function should be added to a major mode hook. It modifies
buffer-local keymaps and adds bindings for Python text objects for
both operator state and visual state."
(interactive)
(when evil-text-object-python-statement-key
(evil-text-object-python--define-key
evil-text-object-python-statement-key
evil-inner-text-objects-map
'evil-text-object-python-inner-statement)
(evil-text-object-python--define-key
evil-text-object-python-statement-key
evil-outer-text-objects-map
'evil-text-object-python-outer-statement))
(when evil-text-object-python-function-key
(evil-text-object-python--define-key
evil-text-object-python-function-key
evil-inner-text-objects-map
'evil-text-object-python-function)))
(provide 'evil-text-object-python)
;;; evil-text-object-python.el ends here