;;; indent.el --- indentation commands for Emacs -*- lexical-binding:t -*-
-;; Copyright (C) 1985, 1995, 2001-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1995, 2001-2016 Free Software Foundation, Inc.
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Package: emacs
;; This file is part of GNU Emacs.
;; indenting. Replace with something ad-hoc.
(let ((column (save-excursion
(beginning-of-line)
- (skip-chars-backward "\n \t")
- (beginning-of-line)
- (current-indentation))))
+ (if (bobp) 0
+ (beginning-of-line 0)
+ (if (looking-at "[ \t]*$") 0
+ (current-indentation))))))
(if (<= (current-column) (current-indentation))
(indent-line-to column)
(save-excursion (indent-line-to column))))
;; The normal case.
(funcall indent-line-function)))
+(defun indent--default-inside-comment ()
+ (unless (or (> (current-column) (current-indentation))
+ (eq this-command last-command))
+ (let ((ppss (syntax-ppss)))
+ (when (nth 4 ppss)
+ (indent-line-to
+ (save-excursion
+ (forward-line -1)
+ (skip-chars-forward " \t")
+ (when (< (1- (point)) (nth 8 ppss) (line-end-position))
+ (goto-char (nth 8 ppss))
+ (when (looking-at comment-start-skip)
+ (goto-char (match-end 0))))
+ (current-column)))
+ t))))
+
(defun indent-for-tab-command (&optional arg)
"Indent the current line or region, or insert a tab, as appropriate.
This function either inserts a tab, or indents the current line,
(old-indent (current-indentation)))
;; Indent the line.
- (funcall indent-line-function)
+ (or (not (eq (funcall indent-line-function) 'noindent))
+ (indent--default-inside-comment)
+ (when (or (<= (current-column) (current-indentation))
+ (not (eq tab-always-indent 'complete)))
+ (funcall (default-value 'indent-line-function))))
(cond
;; If the text was already indented right, try completion.
(interactive "r\nP\np")
(if (and (not arg) interactive)
(progn
- (message "Edit region indentation with <left>, <right>, <S-left> \
-and <S-right>.")
- (set-temporary-overlay-map indent-rigidly-map t))
+ (message
+ (substitute-command-keys
+ "Indent region with \\<indent-rigidly-map>\\[indent-rigidly-left], \\[indent-rigidly-right], \\[indent-rigidly-left-to-tab-stop], or \\[indent-rigidly-right-to-tab-stop]."))
+ (set-transient-map indent-rigidly-map t))
(save-excursion
(goto-char end)
(setq end (point-marker))
(indent-to (max 0 (+ indent (prefix-numeric-value arg))) 0))
(delete-region (point) (progn (skip-chars-forward " \t") (point))))
(forward-line 1))
- (move-marker end nil))))
+ (move-marker end nil)
+ ;; Keep the active region in transient mode.
+ (when (eq (cadr overriding-terminal-local-map) indent-rigidly-map)
+ (setq deactivate-mark nil)))))
(defun indent-rigidly--pop-undo ()
(and (memq last-command '(indent-rigidly-left indent-rigidly-right
(indent-rigidly--pop-undo)
(let* ((current (indent-rigidly--current-indentation beg end))
(rtl (eq (current-bidi-paragraph-direction) 'right-to-left))
- (next (indent--next-tab-stop current (if rtl nil 'prev))))
+ (next (indent-next-tab-stop current (if rtl nil 'prev))))
(indent-rigidly beg end (- next current))))
(defun indent-rigidly-right-to-tab-stop (beg end)
(indent-rigidly--pop-undo)
(let* ((current (indent-rigidly--current-indentation beg end))
(rtl (eq (current-bidi-paragraph-direction) 'right-to-left))
- (next (indent--next-tab-stop current (if rtl 'prev))))
+ (next (indent-next-tab-stop current (if rtl 'prev))))
(indent-rigidly beg end (- next current))))
(defun indent-line-to (column)
"Indent current line to COLUMN.
This function removes or adds spaces and tabs at beginning of line
only if necessary. It leaves point at end of indentation."
- (back-to-indentation)
+ (backward-to-indentation 0)
(let ((cur-col (current-column)))
(cond ((< cur-col column)
(if (>= (- column (* (/ cur-col tab-width) tab-width)) tab-width)
(indent-to column))
((> cur-col column) ; too far right (after tab?)
(delete-region (progn (move-to-column column t) (point))
- (progn (back-to-indentation) (point)))))))
+ (progn (backward-to-indentation 0) (point)))))))
(defun current-left-margin ()
"Return the left margin to use for this line.
;; In most cases, reindenting modifies the buffer, but it may also
;; leave it unmodified, in which case we have to deactivate the mark
;; by hand.
- (deactivate-mark))
+ (setq deactivate-mark t))
(defun indent-relative-maybe ()
"Indent a new line like previous nonblank line.
(move-marker opoint nil))
(tab-to-tab-stop))))
-(defcustom tab-stop-list
- nil
+(defcustom tab-stop-list nil
"List of tab stop positions used by `tab-to-tab-stop'.
-This should be a list of integers, ordered from smallest to largest.
-It implicitly extends to infinity by repeating the last step (e.g. '(1 2 5)
-is equivalent to '(1 2 5 8 11)).
-If the list has less than 2 elements, `tab-width' is used as the \"last step\"."
+This should be nil, or a list of integers, ordered from smallest to largest.
+It implicitly extends to infinity through repetition of the last step.
+For example, (1 2 5) is equivalent to (1 2 5 8 11 ...). If the list has
+fewer than 2 elements, `tab-width' is used as the \"last step\".
+A value of nil means a tab stop every `tab-width' columns."
:group 'indent
+ :version "24.4" ; from explicit list to nil
+ :safe 'listp
:type '(repeat integer))
-(put 'tab-stop-list 'safe-local-variable 'listp)
(defvar edit-tab-stops-map
(let ((map (make-sparse-keymap)))
(setq tab-stop-list tabs))
(message "Tab stops installed"))
-(defun indent--next-tab-stop (column &optional prev)
+(defun indent-next-tab-stop (column &optional prev)
"Return the next tab stop after COLUMN.
If PREV is non-nil, return the previous one instead."
(let ((tabs tab-stop-list))
(if (<= column last) -1 (/ (- column last 1) step))
(1+ (/ (- column last) step)))))))))
+(defun indent-accumulate-tab-stops (limit)
+ "Get a list of tab stops before LIMIT (inclusive)."
+ (let ((tab 0) (tab-stops))
+ (while (<= (setq tab (indent-next-tab-stop tab)) limit)
+ (push tab tab-stops))
+ (nreverse tab-stops)))
+
(defun tab-to-tab-stop ()
"Insert spaces or tabs to next defined tab-stop column.
The variable `tab-stop-list' is a list of columns at which there are tab stops.
(interactive)
(and abbrev-mode (= (char-syntax (preceding-char)) ?w)
(expand-abbrev))
- (let ((nexttab (indent--next-tab-stop (current-column))))
+ (let ((nexttab (indent-next-tab-stop (current-column))))
(delete-horizontal-space t)
(indent-to nexttab)))
The variable `tab-stop-list' is a list of columns at which there are tab stops.
Use \\[edit-tab-stops] to edit them interactively."
(interactive)
- (let ((nexttab (indent--next-tab-stop (current-column))))
+ (let ((nexttab (indent-next-tab-stop (current-column))))
(let ((before (point)))
(move-to-column nexttab t)
(save-excursion