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