Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d48c4a

Browse files
committed
(py-backspace-function): New variable.
(py-electric-backspace, py-electric-delete): Support the XEmacs 20 Way for backspace and delete mappings. In XEmacs 19, Emacs 19, and Emacs 20, both backspace and delete keysyms are bound to py-electric-backspace. In XEmacs 20, backspace and delete keysyms are bound separately, allowing the user to specify forward or backward deletion of the delete keysym through the variable delete-key-deletes-forward. All this is the Right Way To Do It and this implementation was largely ripped from CC Mode.
1 parent a97a3f3 commit 6d48c4a

1 file changed

Lines changed: 101 additions & 60 deletions

File tree

Misc/python-mode.el

Lines changed: 101 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,17 @@ the Emacs bell is also rung as a warning."
216216
:type 'boolean
217217
:group 'python)
218218

219+
(defcustom py-backspace-function 'backward-delete-char-untabify
220+
"*Function called by `py-electric-backspace' when deleting backwards."
221+
:type 'function
222+
:group 'python)
223+
224+
(defcustom py-delete-function 'delete-char
225+
"*Function called by `py-electric-delete' when deleting forwards."
226+
:type 'function
227+
:group 'python)
228+
229+
219230

220231
;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
221232
;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
@@ -271,12 +282,6 @@ When non-nil, arguments are printed.")
271282
"Queue of Python temp files awaiting execution.
272283
Currently-active file is at the head of the list.")
273284

274-
(defvar py-delete-function 'backward-delete-char-untabify
275-
"*Function called by `py-delete-char' when deleting characters.")
276-
277-
(defvar py-backspace-function 'backward-delete-char-untabify
278-
"*Function called by `py-backspace-command' when deleting characters.")
279-
280285

281286
;; Constants
282287

@@ -380,45 +385,59 @@ Currently-active file is at the head of the list.")
380385
(if py-mode-map
381386
nil
382387
(setq py-mode-map (make-sparse-keymap))
383-
388+
;; electric keys
389+
(define-key py-mode-map ":" 'py-electric-colon)
390+
;; indentation level modifiers
391+
(define-key py-mode-map "\C-c\C-l" 'py-shift-region-left)
392+
(define-key py-mode-map "\C-c\C-r" 'py-shift-region-right)
393+
(define-key py-mode-map "\C-c<" 'py-shift-region-left)
394+
(define-key py-mode-map "\C-c>" 'py-shift-region-right)
395+
;; subprocess commands
396+
(define-key py-mode-map "\C-c\C-c" 'py-execute-buffer)
397+
(define-key py-mode-map "\C-c|" 'py-execute-region)
398+
(define-key py-mode-map "\C-c!" 'py-shell)
399+
;; Caution! Enter here at your own risk. We are trying to support
400+
;; several behaviors and it gets disgusting. :-( This logic ripped
401+
;; largely from CC Mode.
402+
;;
403+
;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
404+
;; backwards deletion behavior to DEL, which both Delete and
405+
;; Backspace get translated to. There's no way to separate this
406+
;; behavior in a clean way, so deal with it! Besides, it's been
407+
;; this way since the dawn of time.
408+
(if (not (boundp 'delete-key-deletes-forward))
409+
(define-key py-mode-map "\177" 'py-electric-backspace)
410+
;; However, XEmacs 20 actually achieved enlightenment. It is
411+
;; possible to sanely define both backward and forward deletion
412+
;; behavior under X separately (TTYs are forever beyond hope, but
413+
;; who cares? XEmacs 20 does the right thing with these too).
414+
(define-key py-mode-map [delete] 'py-electric-delete)
415+
(define-key py-mode-map [backspace] 'py-electric-backspace))
416+
;; Miscellaneous
417+
(define-key py-mode-map "\C-c:" 'py-guess-indent-offset)
418+
(define-key py-mode-map "\C-c\t" 'py-indent-region)
419+
(define-key py-mode-map "\C-c\C-n" 'py-next-statement)
420+
(define-key py-mode-map "\C-c\C-p" 'py-previous-statement)
421+
(define-key py-mode-map "\C-c\C-u" 'py-goto-block-up)
422+
(define-key py-mode-map "\C-c\C-m" 'py-mark-block)
423+
(define-key py-mode-map "\C-c#" 'py-comment-region)
424+
(define-key py-mode-map "\C-c?" 'py-describe-mode)
425+
(define-key py-mode-map "\C-c\C-hm" 'py-describe-mode)
426+
(define-key py-mode-map "\e\C-a" 'beginning-of-python-def-or-class)
427+
(define-key py-mode-map "\e\C-e" 'end-of-python-def-or-class)
428+
(define-key py-mode-map "\e\C-h" 'mark-python-def-or-class)
429+
;; information
430+
(define-key py-mode-map "\C-c\C-b" 'py-submit-bug-report)
431+
(define-key py-mode-map "\C-c\C-v" 'py-version)
432+
;; py-newline-and-indent mappings
433+
(define-key py-mode-map "\n" 'py-newline-and-indent)
384434
;; shadow global bindings for newline-and-indent w/ the py- version.
385435
;; BAW - this is extremely bad form, but I'm not going to change it
386436
;; for now.
387437
(mapcar (function (lambda (key)
388438
(define-key
389439
py-mode-map key 'py-newline-and-indent)))
390440
(where-is-internal 'newline-and-indent))
391-
392-
;; BAW - you could do it this way, but its not considered proper
393-
;; major-mode form.
394-
(mapcar (function
395-
(lambda (x)
396-
(define-key py-mode-map (car x) (cdr x))))
397-
'((":" . py-electric-colon)
398-
("\C-c\C-c" . py-execute-buffer)
399-
("\C-c|" . py-execute-region)
400-
("\C-c!" . py-shell)
401-
("\177" . py-delete-char)
402-
("\n" . py-newline-and-indent)
403-
("\C-c:" . py-guess-indent-offset)
404-
("\C-c\t" . py-indent-region)
405-
("\C-c\C-l" . py-shift-region-left)
406-
("\C-c\C-r" . py-shift-region-right)
407-
("\C-c<" . py-shift-region-left)
408-
("\C-c>" . py-shift-region-right)
409-
("\C-c\C-n" . py-next-statement)
410-
("\C-c\C-p" . py-previous-statement)
411-
("\C-c\C-u" . py-goto-block-up)
412-
("\C-c\C-m" . py-mark-block)
413-
("\C-c#" . py-comment-region)
414-
("\C-c?" . py-describe-mode)
415-
("\C-c\C-hm" . py-describe-mode)
416-
("\e\C-a" . beginning-of-python-def-or-class)
417-
("\e\C-e" . end-of-python-def-or-class)
418-
( "\e\C-h" . mark-python-def-or-class)))
419-
;; should do all keybindings this way
420-
(define-key py-mode-map "\C-c\C-b" 'py-submit-bug-report)
421-
(define-key py-mode-map "\C-c\C-v" 'py-version)
422441
)
423442

424443
(defvar py-mode-syntax-table nil
@@ -1048,60 +1067,82 @@ See the `\\[py-execute-region]' docs for an account of some subtleties."
10481067
(py-execute-region (point-min) (point-max) async))
10491068

10501069

1051-
;; Functions for Python style indentation
1052-
(defun py-delete-char (count)
1053-
"Reduce indentation or delete character.
1070+
;; Electric deletion
1071+
(defun py-electric-backspace (arg)
1072+
"Deletes preceding character or levels of indentation.
1073+
Deletion is performed by calling the function in `py-backspace-function'
1074+
with a single argument (the number of characters to delete).
10541075
10551076
If point is at the leftmost column, deletes the preceding newline.
1056-
Deletion is performed by calling the function in `py-delete-function'
1057-
with a single argument (the number of characters to delete).
10581077
1059-
Else if point is at the leftmost non-blank character of a line that is
1060-
neither a continuation line nor a non-indenting comment line, or if
1061-
point is at the end of a blank line, reduces the indentation to match
1062-
that of the line that opened the current block of code. The line that
1063-
opened the block is displayed in the echo area to help you keep track
1064-
of where you are. With numeric count, outdents that many blocks (but
1065-
not past column zero).
1066-
1067-
Else the preceding character is deleted, converting a tab to spaces if
1068-
needed so that only a single column position is deleted. Numeric
1069-
argument delets that many characters."
1078+
Otherwise, if point is at the leftmost non-whitespace character of a
1079+
line that is neither a continuation line nor a non-indenting comment
1080+
line, or if point is at the end of a blank line, this command reduces
1081+
the indentation to match that of the line that opened the current
1082+
block of code. The line that opened the block is displayed in the
1083+
echo area to help you keep track of where you are. With numeric arg,
1084+
outdents that many blocks (but not past column zero).
1085+
1086+
Otherwise the preceding character is deleted, converting a tab to
1087+
spaces if needed so that only a single column position is deleted.
1088+
Numeric argument deletes that many preceding characters."
10701089
(interactive "*p")
10711090
(if (or (/= (current-indentation) (current-column))
10721091
(bolp)
10731092
(py-continuation-line-p)
10741093
(not py-honor-comment-indentation)
10751094
(looking-at "#[^ \t\n]")) ; non-indenting #
1076-
(funcall py-delete-function count)
1095+
(funcall py-backspace-function arg)
10771096
;; else indent the same as the colon line that opened the block
1078-
10791097
;; force non-blank so py-goto-block-up doesn't ignore it
10801098
(insert-char ?* 1)
10811099
(backward-char)
10821100
(let ((base-indent 0) ; indentation of base line
10831101
(base-text "") ; and text of base line
10841102
(base-found-p nil))
10851103
(save-excursion
1086-
(while (< 0 count)
1104+
(while (< 0 arg)
10871105
(condition-case nil ; in case no enclosing block
10881106
(progn
10891107
(py-goto-block-up 'no-mark)
10901108
(setq base-indent (current-indentation)
10911109
base-text (py-suck-up-leading-text)
10921110
base-found-p t))
10931111
(error nil))
1094-
(setq count (1- count))))
1112+
(setq arg (1- arg))))
10951113
(delete-char 1) ; toss the dummy character
10961114
(delete-horizontal-space)
10971115
(indent-to base-indent)
10981116
(if base-found-p
10991117
(message "Closes block: %s" base-text)))))
11001118

1119+
1120+
(defun py-electric-delete (arg)
1121+
"Deletes preceding or following character or levels of whitespace.
1122+
1123+
The behavior of this function depends on the variable
1124+
`delete-key-deletes-forward'. If this variable is nil (or does not
1125+
exist, as in older Emacsen), then this function behaves identical to
1126+
\\[c-electric-backspace].
1127+
1128+
If `delete-key-deletes-forward' is non-nil and is supported in your
1129+
Emacs, then deletion occurs in the forward direction, by calling the
1130+
function in `py-delete-function'."
1131+
(interactive "*p")
1132+
(if (and (boundp 'delete-key-deletes-forward)
1133+
delete-key-deletes-forward)
1134+
(funcall py-delete-function arg)
1135+
;; else
1136+
(py-electric-backspace arg)))
1137+
11011138
;; required for pending-del and delsel modes
1102-
(put 'py-delete-char 'delete-selection 'supersede)
1103-
(put 'py-delete-char 'pending-delete 'supersede)
1139+
(put 'py-electric-backspace 'delete-selection 'supersede) ;delsel
1140+
(put 'py-electric-backspace 'pending-delete 'supersede) ;pending-del
1141+
(put 'py-electric-delete 'delete-selection 'supersede) ;delsel
1142+
(put 'py-electric-delete 'pending-delete 'supersede) ;pending-del
1143+
11041144

1145+
11051146
(defun py-indent-line (&optional arg)
11061147
"Fix the indentation of the current line according to Python rules.
11071148
With \\[universal-argument], ignore outdenting rules for block

0 commit comments

Comments
 (0)