+(defun indent-for-tab-command (&optional arg)
+ "Indent line in proper way for current major mode or insert a tab.
+Depending on `tab-always-indent', either insert a tab or indent.
+If initial point was within line's indentation, position after
+the indentation. Else stay at same point in text.
+The function actually called to indent is determined by the value of
+`indent-line-function'."
+ (interactive "P")
+ (cond
+ ((or ;; indent-to-left-margin is only meant for indenting,
+ ;; so we force it to always insert a tab here.
+ (eq indent-line-function 'indent-to-left-margin)
+ (and (not tab-always-indent)
+ (or (> (current-column) (current-indentation))
+ (eq this-command last-command))))
+ (insert-tab arg))
+ ;; Those functions are meant specifically for tabbing and not for
+ ;; indenting, so we can't pass them to indent-according-to-mode.
+ ((memq indent-line-function '(indent-relative indent-relative-maybe))
+ (funcall indent-line-function))
+ (t ;; The normal case.
+ (indent-according-to-mode))))
+
+(defun insert-tab (&optional arg)
+ (let ((count (prefix-numeric-value arg)))
+ (if (and abbrev-mode
+ (eq (char-syntax (preceding-char)) ?w))
+ (expand-abbrev))
+ (if indent-tabs-mode
+ (insert-char ?\t count)
+ (indent-to (* tab-width (+ count (/ (current-column) tab-width)))))))