Summary: demonstrate concise number sequence generation
< Using a little piece of elisp or some manual editing, you can change
> Using some manual editing, you can change this:
< Here is the little fragment I used:
< (let ((i 4))
< (while (< i 124)
< (insert (number-to-string i) " ")
< (setq i (+ 4 i))))
< Or even this:
< (setq tab-stop-list (let ((stops '(8)))
< (while (< (car stops) 120)
< (setq stops (cons (+ 8 (car stops)) stops)))
< (nreverse stops)))
< Or just:
< (setq tab-stop-list (mapcar (lambda (x) (* 4 x))
< (number-sequence 1 (/ 120 4))))
< Or perhaps:
< (setq tab-stop-list (loop for i from 4 to 120 by 4 collect i))
< The last only if you have used the CommonLisp package.
> Or have elisp generate the list for you:
> (setq tab-stop-list (number-sequence 4 120 4))
‘tab-stop-list’ holds a list of all the tab stops to use, when
‘indent-relative’ does not find an appropriate tab stop. It is the fallback used most often.
Some people use
‘tab-to-tab-stop’ as their indentation function. Then
‘tab-stop-list’ is the only variable used. You can do that as well:
(define-key text-mode-map (kbd "<tab>") 'tab-to-tab-stop)
The default tab stops are 8 spaces appart:
(8 16 24 32 40 48 56 64 72 80 88 96 104 112 120)
Using some manual editing, you can change this:
(setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))
Or have elisp generate the list for you:
(setq tab-stop-list (number-sequence 4 120 4))
Here’s a command to set the tab stop width.
(defun set-tab-stop-width (width) "Set all tab stops to WIDTH in current buffer. This updates `tab-stop-list', but not `tab-width'. By default, `indent-for-tab-command' uses tabs to indent, see `indent-tabs-mode'." (interactive "nTab width: ") (let* ((max-col (car (last tab-stop-list))) ;; If width is not a factor of max-col, ;; then max-col could be reduced with each call. (n-tab-stops (/ max-col width))) (set (make-local-variable 'tab-stop-list) (mapcar (lambda (x) (* width x)) (number-sequence 1 n-tab-stops))) ;; So preserve max-col, by adding to end. (unless (zerop (% max-col width)) (setcdr (last tab-stop-list) (list max-col)))))
In addition to interactive use, it could be added to a mode hook.
(defun local-text-mode-hook-fun () (set-tab-stop-width 2) (setq indent-tabs-mode nil)) (add-hook 'text-mode-hook 'local-text-mode-hook-fun)
Note that this is not the same as the variable
‘tab-width’. That variable only controls how much space a tab character occupies in the buffer. The default value is 8. This fits nicely with the default value of
Now, if you read source code written with an editor that inserts tab, but you want it look as if it was indented using a tab-width of 2, the use the following:
(setq tab-width 2)
Note that if you hit the TAB key, this does not necessarily mean that point will advance by 2! What happens when you hit the TAB key is entirely dependent upon the function bound to it.
If the TAB key is bound to
‘indent-relative’, then – as explained above – the variable
‘tab-stop-list’ may be used as a fallback. And then point will probably advance by 8, not by 2! You could either set
‘tab-stop-list’ accordingly, but probably that just means you have the wrong function bound to the TAB key. Most programming modes provide much better indentation.