unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* dedent in Python-mode
@ 2007-06-24 20:44 Paul Pogonyshev
  2007-06-24 21:30 ` Markus Triska
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-24 20:44 UTC (permalink / raw)
  To: emacs-devel

Hi,

With TAB I can indent a line in Python mode or, actually, cycle through
possible indentations.  Can Shift+TAB (backtab) be made to cycle through
them in opposite direction?  This would make closing a block in Python
mode easier.

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 20:44 dedent in Python-mode Paul Pogonyshev
@ 2007-06-24 21:30 ` Markus Triska
  2007-06-24 21:56   ` Paul Pogonyshev
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Triska @ 2007-06-24 21:30 UTC (permalink / raw)
  To: Paul Pogonyshev; +Cc: emacs-devel

Paul Pogonyshev <pogonyshev@gmx.net> writes:

> With TAB I can indent a line in Python mode or, actually, cycle through
> possible indentations.  Can Shift+TAB (backtab) be made to cycle through
> them in opposite direction?

Please try this patch:

2007-06-24  Markus Triska  <markus.triska@gmx.at>

	* progmodes/python.el (python-indent-line-dir): generalised
	python-indent-line, cycling through indentations in given
	direction
	(python-indent-line): dispatch to python-indent-line-dir
	(python-indent-line-backward): new function


*** python.el	24 Jun 2007 22:43:05 +0200	1.62
--- python.el	24 Jun 2007 23:19:44 +0200	
***************
*** 208,213 ****
--- 208,214 ----
      (define-key map "\C-c\C-v" 'python-check) ; a la sgml-mode
      (define-key map "\C-c\C-s" 'python-send-string)
      (define-key map [?\C-\M-x] 'python-send-defun)
+     (define-key map [backtab]  'python-indent-line-backward)
      (define-key map "\C-c\C-r" 'python-send-region)
      (define-key map "\C-c\M-r" 'python-send-region-and-go)
      (define-key map "\C-c\C-c" 'python-send-buffer)
***************
*** 698,725 ****
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
!   "Indent current line as Python code.
! When invoked via `indent-for-tab-command', cycle through possible
! indentations for current line.  The cycle is broken by a command
! different from `indent-for-tab-command', i.e. successive TABs do
! the cycling."
    (interactive)
!   (if (and (eq this-command 'indent-for-tab-command)
! 	   (eq last-command this-command))
!       (if (= 1 python-indent-list-length)
! 	  (message "Sole indentation")
! 	(progn (setq python-indent-index
! 		     (% (1+ python-indent-index) python-indent-list-length))
! 	       (beginning-of-line)
! 	       (delete-horizontal-space)
! 	       (indent-to (car (nth python-indent-index python-indent-list)))
! 	       (if (python-block-end-p)
! 		   (let ((text (cdr (nth python-indent-index
! 					 python-indent-list))))
! 		     (if text
! 			 (message "Closes: %s" text))))))
!     (python-indent-line-1)
!     (setq python-indent-index (1- python-indent-list-length))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.
--- 699,743 ----
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
!   "Indent current line as Python code, cycling through
! indentations in forward direction. See `python-indent-line-dir'."
    (interactive)
!   (python-indent-line-dir 1))
! 
! (defun python-indent-line-backward ()
!    "Like `python-indent-line', cycling backwards."
!    (interactive)
!    (python-indent-line-dir -1))
! 
! (defun python-indent-line-dir (dir)
! "Indent current line as Python code.
! When invoked via `python-indent-line-backward' or
! `indent-for-tab-command', cycle in direction DIR through possible
! indentations for the current line. The cycle is broken by a
! command different from those, i.e. successive (S-)TABs do the
! cycling."
!   (interactive)
!   (let ((cyclic '(python-indent-line-backward indent-for-tab-command)))
!     (if (and (member this-command cyclic)
! 	     (member last-command cyclic))
! 	(if (= 1 python-indent-list-length)
! 	    (message "Sole indentation")
! 	  (progn
! 	    (setq python-indent-index
! 		  ;; add python-indent-list-length to correctly handle 
! 		  ;; python-indent-index + dir < 0
! 		  (% (+ python-indent-index dir python-indent-list-length)
! 		     python-indent-list-length))
! 	    (beginning-of-line)
! 	    (delete-horizontal-space)
! 	    (indent-to (car (nth python-indent-index python-indent-list)))
! 	    (if (python-block-end-p)
! 		(let ((text (cdr (nth python-indent-index
! 				      python-indent-list))))
! 		  (if text
! 		      (message "Closes: %s" text))))))
!       (python-indent-line-1)
!       (setq python-indent-index (1- python-indent-list-length)))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 21:30 ` Markus Triska
@ 2007-06-24 21:56   ` Paul Pogonyshev
  2007-06-24 22:08     ` Markus Triska
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-24 21:56 UTC (permalink / raw)
  To: emacs-devel; +Cc: Markus Triska

Markus Triska wrote:
> Paul Pogonyshev <pogonyshev@gmx.net> writes:
> 
> > With TAB I can indent a line in Python mode or, actually, cycle through
> > possible indentations.  Can Shift+TAB (backtab) be made to cycle through
> > them in opposite direction?
> 
> Please try this patch:
> 
> [...]

Seems to work, except that for the first key press it doesn't do anything in
some cases.  E.g. hit C-j (I have Enter remapped to its function) twice after
`print ...' and press Shift+Tab.  Only starts working the second time.

class Test ():

    def __init__(self):
        print 'test'

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 21:56   ` Paul Pogonyshev
@ 2007-06-24 22:08     ` Markus Triska
  2007-06-24 22:30       ` Paul Pogonyshev
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Triska @ 2007-06-24 22:08 UTC (permalink / raw)
  To: Paul Pogonyshev; +Cc: emacs-devel

Paul Pogonyshev <pogonyshev@gmx.net> writes:

> Seems to work, except that for the first key press it doesn't do
> anything in some cases.

The first press behaves like TAB; try S-TAB on "abc" in:

class Test ():

    def __init__(self):
        print 'test'

abc

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 22:08     ` Markus Triska
@ 2007-06-24 22:30       ` Paul Pogonyshev
  2007-06-24 23:44         ` Markus Triska
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-24 22:30 UTC (permalink / raw)
  To: emacs-devel; +Cc: Markus Triska

Markus Triska wrote:
> Paul Pogonyshev <pogonyshev@gmx.net> writes:
> 
> > Seems to work, except that for the first key press it doesn't do
> > anything in some cases.
> 
> The first press behaves like TAB; [...]

Hm.  Can it then behave like TAB, but if this doesn't change
indentation at all, then start dedenting from what TAB proposes as
default?  I.e. so that closing block like I wanted to begin with is
easier.  (Since I always use `newline-and-indent', this is important
for me.)

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 22:30       ` Paul Pogonyshev
@ 2007-06-24 23:44         ` Markus Triska
  2007-06-25 18:18           ` Paul Pogonyshev
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Triska @ 2007-06-24 23:44 UTC (permalink / raw)
  To: Paul Pogonyshev; +Cc: emacs-devel

Paul Pogonyshev <pogonyshev@gmx.net> writes:

> Can it then behave like TAB, but if this doesn't change indentation
> at all, then start dedenting from what TAB proposes as default?

Put this in your .emacs:

(defun python-personal-dedent ()
  (interactive)
  (let ((cyclic 'python-indent-line-backward)
	(old (current-indentation)))
    (setq this-command cyclic)
    (python-indent-line-backward)
    (setq last-command cyclic)
    (when (and (> python-indent-list-length 1)
	       (= old (current-indentation)))
      (python-indent-line-backward))))

(add-hook 'python-mode-hook
	  (lambda ()
	    (local-set-key [backtab] 'python-personal-dedent)))

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-24 23:44         ` Markus Triska
@ 2007-06-25 18:18           ` Paul Pogonyshev
  2007-06-25 20:20             ` Markus Triska
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-25 18:18 UTC (permalink / raw)
  To: emacs-devel; +Cc: Markus Triska

Markus Triska wrote:
> Paul Pogonyshev <pogonyshev@gmx.net> writes:
> 
> > Can it then behave like TAB, but if this doesn't change indentation
> > at all, then start dedenting from what TAB proposes as default?
> 
> Put this in your .emacs: [...]

Yeah.  In principle, I could write backtab function in my .emacs as well.
But don't you agree that if I press Shift+Tab and nothing in the buffer
changes, not even the point position, it looks like a little broken?  I
mean, given that it doesn't have "final perfect state" like TAB in other
modes, but cycles through possible indentations?

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-25 18:18           ` Paul Pogonyshev
@ 2007-06-25 20:20             ` Markus Triska
  2007-06-25 20:44               ` Paul Pogonyshev
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Triska @ 2007-06-25 20:20 UTC (permalink / raw)
  To: Paul Pogonyshev; +Cc: emacs-devel

Paul Pogonyshev <pogonyshev@gmx.net> writes:

> Yeah. In principle, I could write backtab function in my .emacs as
> well. But don't you agree that if I press Shift+Tab and nothing in
> the buffer changes, not even the point position, it looks like a
> little broken?

Please try this patch instead of the previous one:

2007-06-25  Markus Triska  <markus.triska@gmx.at>

	* progmodes/python.el (python-indent-propose): new function
	(python-indent-line-dir): generalise python-indent-line, cycling
	in given direction
	(python-indent-line-backward): new function
	(python-indent-line): dispatch to python-indent-line

*** python.el	24 Jun 2007 22:43:05 +0200	1.62
--- python.el	25 Jun 2007 22:13:07 +0200	
***************
*** 197,202 ****
--- 197,203 ----
      ;; Mostly taken from python-mode.el.
      (define-key map ":" 'python-electric-colon)
      (define-key map "\177" 'python-backspace)
+     (define-key map [backtab]  'python-indent-line-backward)
      (define-key map "\C-c<" 'python-shift-left)
      (define-key map "\C-c>" 'python-shift-right)
      (define-key map "\C-c\C-k" 'python-mark-block)
***************
*** 698,725 ****
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
    "Indent current line as Python code.
! When invoked via `indent-for-tab-command', cycle through possible
! indentations for current line.  The cycle is broken by a command
! different from `indent-for-tab-command', i.e. successive TABs do
! the cycling."
    (interactive)
!   (if (and (eq this-command 'indent-for-tab-command)
! 	   (eq last-command this-command))
!       (if (= 1 python-indent-list-length)
! 	  (message "Sole indentation")
! 	(progn (setq python-indent-index
! 		     (% (1+ python-indent-index) python-indent-list-length))
! 	       (beginning-of-line)
! 	       (delete-horizontal-space)
! 	       (indent-to (car (nth python-indent-index python-indent-list)))
! 	       (if (python-block-end-p)
! 		   (let ((text (cdr (nth python-indent-index
! 					 python-indent-list))))
! 		     (if text
! 			 (message "Closes: %s" text))))))
!     (python-indent-line-1)
!     (setq python-indent-index (1- python-indent-list-length))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.
--- 699,751 ----
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
+   "Indent current line as Python code, cycling through
+ indentations in forward direction. See `python-indent-line-dir'."
+   (interactive)
+   (python-indent-line-dir 1))
+ 
+ (defun python-indent-line-backward ()
+    "Like `python-indent-line', cycling backwards."
+    (interactive)
+    (python-indent-line-dir -1))
+ 
+ (defun python-indent-line-dir (dir)
    "Indent current line as Python code.
! When invoked via `python-indent-line-backward' or
! `indent-for-tab-command', cycle in direction DIR through possible
! indentations for the current line. The cycle is broken by a
! command different from those, i.e. successive (S-)TABs cycle."
    (interactive)
!   (let ((cyclic '(python-indent-line-backward indent-for-tab-command)))
!     (if (and (member this-command cyclic)
! 	     (member last-command cyclic))
! 	(if (= 1 python-indent-list-length)
! 	    (message "Sole indentation")
! 	  (progn
! 	    (setq python-indent-index
! 		  ;; add python-indent-list-length to correctly handle
! 		  ;; python-indent-index + dir < 0
! 		  (% (+ python-indent-index dir python-indent-list-length)
! 		     python-indent-list-length))
! 	    (python-indent-propose)))
!       (if (and (= dir -1)
! 	       (= (current-indentation) (python-calculate-indentation))
! 	       (> python-indent-list-length 1))
! 	  (progn
! 	    (setq python-indent-index (- python-indent-list-length 2))
! 	    (python-indent-propose))
! 	(setq python-indent-index (1- python-indent-list-length))
! 	(python-indent-line-1)))))
! 
! (defun python-indent-propose ()
!   "Propose indentation alternative `python-indent-index'."
!   (beginning-of-line)
!   (delete-horizontal-space)
!   (indent-to (car (nth python-indent-index python-indent-list)))
!   (when (python-block-end-p)
!     (let ((text (cdr (nth python-indent-index python-indent-list))))
!       (when text
! 	(message "Closes: %s" text)))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-25 20:44               ` Paul Pogonyshev
@ 2007-06-25 20:36                 ` Markus Triska
  2007-06-25 21:07                   ` Paul Pogonyshev
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Triska @ 2007-06-25 20:36 UTC (permalink / raw)
  To: Paul Pogonyshev; +Cc: emacs-devel

Paul Pogonyshev <pogonyshev@gmx.net> writes:

> doesn't work at all

Sorry, I meant:

2007-06-25  Markus Triska  <markus.triska@gmx.at>

	* progmodes/python.el (python-indent-propose): new function
	(python-indent-line-dir): generalise python-indent-line, cycling
	in given direction
	(python-indent-line-backward): new function
	(python-indent-line): dispatch to python-indent-line-dir


*** python.el	24 Jun 2007 22:43:05 +0200	1.62
--- python.el	25 Jun 2007 22:34:10 +0200	
***************
*** 197,202 ****
--- 197,203 ----
      ;; Mostly taken from python-mode.el.
      (define-key map ":" 'python-electric-colon)
      (define-key map "\177" 'python-backspace)
+     (define-key map [backtab]  'python-indent-line-backward)
      (define-key map "\C-c<" 'python-shift-left)
      (define-key map "\C-c>" 'python-shift-right)
      (define-key map "\C-c\C-k" 'python-mark-block)
***************
*** 698,725 ****
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
    "Indent current line as Python code.
! When invoked via `indent-for-tab-command', cycle through possible
! indentations for current line.  The cycle is broken by a command
! different from `indent-for-tab-command', i.e. successive TABs do
! the cycling."
    (interactive)
!   (if (and (eq this-command 'indent-for-tab-command)
! 	   (eq last-command this-command))
!       (if (= 1 python-indent-list-length)
! 	  (message "Sole indentation")
! 	(progn (setq python-indent-index
! 		     (% (1+ python-indent-index) python-indent-list-length))
! 	       (beginning-of-line)
! 	       (delete-horizontal-space)
! 	       (indent-to (car (nth python-indent-index python-indent-list)))
! 	       (if (python-block-end-p)
! 		   (let ((text (cdr (nth python-indent-index
! 					 python-indent-list))))
! 		     (if text
! 			 (message "Closes: %s" text))))))
!     (python-indent-line-1)
!     (setq python-indent-index (1- python-indent-list-length))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.
--- 699,751 ----
  	  (goto-char (- (point-max) pos))))))
  
  (defun python-indent-line ()
+   "Indent current line as Python code, cycling through
+ indentations in forward direction. See `python-indent-line-dir'."
+   (interactive)
+   (python-indent-line-dir 1))
+ 
+ (defun python-indent-line-backward ()
+    "Like `python-indent-line', cycling backwards."
+    (interactive)
+    (python-indent-line-dir -1))
+ 
+ (defun python-indent-line-dir (dir)
    "Indent current line as Python code.
! When invoked via `python-indent-line-backward' or
! `indent-for-tab-command', cycle in direction DIR through possible
! indentations for the current line. The cycle is broken by a
! command different from those, i.e. successive (S-)TABs cycle."
    (interactive)
!   (let ((cyclic '(python-indent-line-backward indent-for-tab-command)))
!     (if (and (member this-command cyclic)
! 	     (member last-command cyclic))
! 	(if (= 1 python-indent-list-length)
! 	    (message "Sole indentation")
! 	  (progn
! 	    (setq python-indent-index
! 		  ;; add python-indent-list-length to correctly handle
! 		  ;; python-indent-index + dir < 0
! 		  (% (+ python-indent-index dir python-indent-list-length)
! 		     python-indent-list-length))
! 	    (python-indent-propose)))
!       (if (and (= dir -1)
! 	       (= (current-indentation) (python-calculate-indentation))
! 	       (> python-indent-list-length 1))
! 	  (progn
! 	    (setq python-indent-index (- python-indent-list-length 2))
! 	    (python-indent-propose))
! 	(python-indent-line-1)
! 	(setq python-indent-index (1- python-indent-list-length))))))
! 
! (defun python-indent-propose ()
!   "Propose indentation alternative `python-indent-index'."
!   (beginning-of-line)
!   (delete-horizontal-space)
!   (indent-to (car (nth python-indent-index python-indent-list)))
!   (when (python-block-end-p)
!     (let ((text (cdr (nth python-indent-index python-indent-list))))
!       (when text
! 	(message "Closes: %s" text)))))
  
  (defun python-indent-region (start end)
    "`indent-region-function' for Python.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-25 20:20             ` Markus Triska
@ 2007-06-25 20:44               ` Paul Pogonyshev
  2007-06-25 20:36                 ` Markus Triska
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-25 20:44 UTC (permalink / raw)
  To: emacs-devel; +Cc: Markus Triska

Markus Triska wrote:
> Paul Pogonyshev <pogonyshev@gmx.net> writes:
> 
> > Yeah. In principle, I could write backtab function in my .emacs as
> > well. But don't you agree that if I press Shift+Tab and nothing in
> > the buffer changes, not even the point position, it looks like a
> > little broken?
> 
> Please try this patch instead of the previous one:

Sorry, doesn't work at all here:

class Test ():

I put point right after (): and evaluate (newline-and-indent):

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
  1-(nil)
  (setq python-indent-index (1- python-indent-list-length))
  (if (and (= dir -1) (= ... ...) (> python-indent-list-length 1)) (progn (setq python-indent-index ...) (python-indent-propose)) (setq python-indent-index (1- python-indent-list-length)) (python-indent-line-1))
  (if (and (member this-command cyclic) (member last-command cyclic)) (if (= 1 python-indent-list-length) (message "Sole indentation") (progn ... ...)) (if (and ... ... ...) (progn ... ...) (setq python-indent-index ...) (python-indent-line-1)))
  (let ((cyclic ...)) (if (and ... ...) (if ... ... ...) (if ... ... ... ...)))
  python-indent-line-dir(1)
  python-indent-line()
  indent-according-to-mode()
  newline-and-indent()
  eval((newline-and-indent))
  eval-expression((newline-and-indent) nil)
  call-interactively(eval-expression)

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dedent in Python-mode
  2007-06-25 20:36                 ` Markus Triska
@ 2007-06-25 21:07                   ` Paul Pogonyshev
  0 siblings, 0 replies; 11+ messages in thread
From: Paul Pogonyshev @ 2007-06-25 21:07 UTC (permalink / raw)
  To: emacs-devel; +Cc: Markus Triska

Markus Triska wrote:
> Paul Pogonyshev <pogonyshev@gmx.net> writes:
> 
> > doesn't work at all
> 
> Sorry, I meant:

Thanks, this is what I wanted.  Maybe I'd actually prefer Shift+Tab to
not first indent to the default value, rather to just cycle through
possible indentations starting from the current level.  But I see why
more similar Tab / Shift+Tab is important too.

Thank you for the patch.  I hope it gets to the trunk soon :)

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-06-25 21:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-24 20:44 dedent in Python-mode Paul Pogonyshev
2007-06-24 21:30 ` Markus Triska
2007-06-24 21:56   ` Paul Pogonyshev
2007-06-24 22:08     ` Markus Triska
2007-06-24 22:30       ` Paul Pogonyshev
2007-06-24 23:44         ` Markus Triska
2007-06-25 18:18           ` Paul Pogonyshev
2007-06-25 20:20             ` Markus Triska
2007-06-25 20:44               ` Paul Pogonyshev
2007-06-25 20:36                 ` Markus Triska
2007-06-25 21:07                   ` Paul Pogonyshev

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).