unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* More intelligent command for C-x TAB (understand also tab-stop-list)
@ 2013-07-13  6:41 Teemu Likonen
  2013-07-13 23:30 ` Xue Fuqiao
  0 siblings, 1 reply; 3+ messages in thread
From: Teemu Likonen @ 2013-07-13  6:41 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 4591 bytes --]

I propose binding a new command to C-x TAB. This new command would have
all the functionality of the current command (indent-rigidly) but also
added intelligence to understand tab-stop-list.

I have discussed this in #8196:
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8196>. But as there was
some misunderstanding I try to write a better explanation here.

The current C-x TAB command (indent-rigidly) command moves region
forward or backward by the number of columns given as prefix argument.
If user does not give the command a prefix argument the default is to
move by 1 column.

My proposed new C-x TAB command would do the same thing as
indent-rigidly when given a numeric prefix argument. There would be
difference only when user doesn't give it a numeric prefix argument. In
such case the new C-x TAB command would move the region to the next or
previous tab stop as defined in the tab-stop-list variable. The lowest
indentation level of the region would be moved to the tab stop column.

Here's a concrete editing example. We have defined tab-stop-list
variable as (4 8 12 16 20 etc.) and we have a buffer with the following
text:

 (defun foo ()
   (some-code)
   (more-code))

Now I mark the above piece of code with M-h and execute "M-x
indent-rigidly". The result is this:

  (defun foo ()
    (some-code)
    (more-code))

The text advances by one column. With my proposed new command it would
move to the next tab stop column:

    (defun foo ()
      (some-code)
      (more-code))

The lowest indentation point of that region is now at column 4 because
that's the next tab stop defined in tab-stop-list variable. In my
proposed new command there is a repeat feature too. If I keep on
repeating TAB (that is, C-x TAB TAB TAB) the region would move to the
next tab stops: 8, 12, 16, 20 etc.

With the negative non-numeric prefix argument (C-u -) my proposed
command would do the same but go to the previous tab stop column as
defined in tab-stop-list variable.

The name for this new command could be "indent-region-to-tab-stop", for
example, and it relies on "indent-region" to do the actual job.

For those who want to try this command just evaluate the code below.
Emacs developers are free to use the code because I have done the
copyright-assignment paperwork for FSF.


--8<---------------cut here---------------start------------->8---
(defun region-indentation (beg end)
  "Return the smallest indentation in range from BEG to END.
Blank lines are ignored."
  (save-excursion
    (let ((beg (progn (goto-char beg) (line-beginning-position)))
          indent)
      (goto-char beg)
      (while (re-search-forward "^\\s-*[[:print:]]" end t)
        (setq indent (min (or indent (current-indentation))
                          (current-indentation))))
      indent)))


(defun indent-region-to-tab-stop-engine (beg end arg)
  "Back-end function for `indent-region-to-tab-stop'."
  (interactive "r\nP")
  (let* ((beg (save-excursion (goto-char beg) (line-beginning-position)))
         (current (region-indentation beg end))
         (indent (cond ((not arg)
                        (- (catch 'answer
                             (dolist (col tab-stop-list (1+ current))
                               (when (> col current)
                                 (throw 'answer col))))
                           current))
                       ((eq arg '-)
                        (- (catch 'answer
                             (dolist (col (reverse tab-stop-list) 0)
                               (when (< col current)
                                 (throw 'answer col))))
                           current))
                       (t (prefix-numeric-value arg)))))
    (indent-rigidly beg end indent)))


(defun indent-region-to-tab-stop (beg end arg)
  "Indent region to a tab stop column or to the specified column.

Indent the region from BEG to END according to the command's
prefix argument ARG. If ARG is nil (i.e., there is no prefix
argument) indent the region to the next tab stop column in
`tab-stop-list'. With negative prefix ARG (C-u -) indent the
region to the previous tab stop column. If ARG is an integer
indent the region by ARG columns (just like `indent-rigidly'
command).

If this command is invoked by a multi-character key sequence, it
can be repeated by repeating the final character of the
sequence."

  (interactive "r\nP")
  (require 'repeat)
  (let ((repeat-message-function 'ignore))
    (setq last-repeatable-command 'indent-region-to-tab-stop-engine)
    (repeat nil)))
--8<---------------cut here---------------end--------------->8---

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

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

* Re: More intelligent command for C-x TAB (understand also tab-stop-list)
  2013-07-13  6:41 More intelligent command for C-x TAB (understand also tab-stop-list) Teemu Likonen
@ 2013-07-13 23:30 ` Xue Fuqiao
  2013-07-14 15:06   ` Teemu Likonen
  0 siblings, 1 reply; 3+ messages in thread
From: Xue Fuqiao @ 2013-07-13 23:30 UTC (permalink / raw)
  To: Teemu Likonen; +Cc: emacs-devel

On Sat, Jul 13, 2013 at 2:41 PM, Teemu Likonen <tlikonen@iki.fi> wrote:
> I propose binding a new command to C-x TAB. This new command would have
> all the functionality of the current command (indent-rigidly) but also
> added intelligence to understand tab-stop-list.
[...]
> For those who want to try this command just evaluate the code below.
> Emacs developers are free to use the code because I have done the
> copyright-assignment paperwork for FSF.

Sounds fine to me, and I made a modified version for the doc string of
i-r-t-t-s.  I put two spaces at the end of a sentence, and there are
some other minor changes:

  "Indent region to a tab stop column or to the specified column.

Indent the region from BEG to END according to the command's
prefix argument ARG.  If ARG is nil (i.e., there is no prefix
argument) indent the region to the next tab stop column in
`tab-stop-list'.  With a negative prefix ARG (e.g., \"C-u -\"),
indent the region to the previous tab stop column.  If ARG is an
integer indent the region by ARG columns (just like
`indent-rigidly' command).

If this command is invoked by a multi-character key sequence, it
can be repeated by repeating the final character of the
sequence."

--
Best regards, Xue Fuqiao.
http://www.gnu.org/software/emacs/



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

* Re: More intelligent command for C-x TAB (understand also tab-stop-list)
  2013-07-13 23:30 ` Xue Fuqiao
@ 2013-07-14 15:06   ` Teemu Likonen
  0 siblings, 0 replies; 3+ messages in thread
From: Teemu Likonen @ 2013-07-14 15:06 UTC (permalink / raw)
  To: Xue Fuqiao; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 545 bytes --]

Xue Fuqiao [2013-07-14 07:30:08 +08:00] wrote:

> Sounds fine to me, and I made a modified version for the doc string of
> i-r-t-t-s.

Thanks.

In the bug report thread (#8196) Stefan suggested that without a prefix
argument C-x TAB could enter an interactive editing mode in which <left>
and <right> keys edit the region's indentation. I wrote an
implementation of the idea and added <S-left> and <S-right> for moving
to the previous or next tab stop.

Maybe we can move the discussion there?

http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8196

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

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

end of thread, other threads:[~2013-07-14 15:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-13  6:41 More intelligent command for C-x TAB (understand also tab-stop-list) Teemu Likonen
2013-07-13 23:30 ` Xue Fuqiao
2013-07-14 15:06   ` Teemu Likonen

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).