@@ -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.
272283Currently-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 " \1 77" '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- (" \1 77" . 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
10551076If 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.
11071148With \\ [universal-argument], ignore outdenting rules for block
0 commit comments