让 Tab键和 S-TAB 缩进正确[仅供参考]

因为 Emacs 的每个 major mode 所使用的缩进配置都不一样,有时候我们只想像其他编辑器一样使用 TAB 来缩进,Shift+TAB 向后缩进。

往你的配置中添加以下代码就可以啦:

   ;; my fix for tab indent
(defun zilongshanren/indent-region(numSpaces)
  (progn
                                      ; default to start and end of current line
    (setq regionStart (line-beginning-position))
    (setq regionEnd (line-end-position))

                                      ; if there's a selection, use that instead of the current line
    (when (use-region-p)
      (setq regionStart (region-beginning))
      (setq regionEnd (region-end))
      )

    (save-excursion                          ; restore the position afterwards
      (goto-char regionStart)                ; go to the start of region
      (setq start (line-beginning-position)) ; save the start of the line
      (goto-char regionEnd)                  ; go to the end of region
      (setq end (line-end-position))         ; save the end of the line

      (indent-rigidly start end numSpaces) ; indent between start and end
      (setq deactivate-mark nil)           ; restore the selected region
      )
    )
  )


(defun zilongshanren/tab-region ()
  (interactive "p")
  (if (use-region-p)
      (zilongshanren/indent-region 4)               ; region was selected, call indent-region
    (insert "    ")                   ; else insert four spaces as expected
    ))

(defun zilongshanren/untab-region ()
  (interactive "p")
  (zilongshanren/indent-region -4))

(defun zilongshanren/hack-tab-key ()
  (interactive)
  (local-set-key (kbd "<tab>") 'zilongshanren/tab-region)
  (local-set-key (kbd "<S-tab>") 'zilongshanren/untab-region)
  )

(add-hook 'prog-mode-hook 'zilongshanren/hack-tab-key)

Ref: Emacs Shift-Tab to left shift the block - Stack Overflow

@XCREATES

5 个赞

目前,如果使用 spacemacs 的同学,可能 html mode 的 tab key 会无效,那是因为:

      (evil-define-key 'insert emmet-mode-keymap (kbd "TAB") 'emmet-expand-yas)
      (evil-define-key 'insert emmet-mode-keymap (kbd "<tab>") 'emmet-expand-yas)
      (evil-define-key 'emacs emmet-mode-keymap (kbd "TAB") 'emmet-expand-yas)
      (evil-define-key 'emacs emmet-mode-keymap (kbd "<tab>") 'emmet-expand-yas)
      (evil-define-key 'hybrid emmet-mode-keymap (kbd "TAB") 'emmet-expand-yas)
      (evil-define-key 'hybrid emmet-mode-keymap (kbd "<tab>") 'emmet-expand-yas)

如果你不用 emmet-mode 可以 exclude 掉,如果想继续使用 TAB key, 可以 clear 上面定义的 Key bindings。

我平时不怎么写 HTML,我把 emmet-mode exclude 了,所以这个对我没有影响。

另外,当选中一段文本的时候,使用这个方法也可以正确地 indent, Emacs Rocks!

1 个赞

好的,不过TAB在org里面定义的特别复杂,比较喜欢在Normal State下,TAB的收放当前等级的功能。

我只在 prog-mode-hook 添加这个修改,markdown-mode 和 org-mode 并不受影响

你用Java多久了。

这个跟 Java 有什么关系?我用 Java 10 年了吧。。。

hahahaha coding style. Simply curious lol.

感觉这两个参数都没用,是不是应该作为zilongshanren/indent-region的参数?

恩,是的,谢谢指出。 我直接去掉了 N 这个参数。

你没有理解我的意思,prog-mode一般都可以代码折叠,如果在Normal State下TAB可以进行代码折叠,在insert State下在使用你的缩进,岂不是更方便。

恩,不过我基本不怎么使用代码折叠这个功能。。。 我把这个缩进的去掉了,还是有些时候不太好用。

我的spacemacs 的制表符我改为了4,但是写makefile的时候还是make不过。 不知道是哪里没设置好。

我印象中 Makefile 是强制用 TAB 缩进,至于 tab-width 设为多少没关系。

但是make不过,我每次写好makefile,都还要在vim里修改一下才能make过

把不正确的与正确的比对下不就知道什么地方出问题了。make 不通过也会提供为什么不过。

好像可以了,不知道昨天咋回事!! 谢谢

没有N之后我一执行就报错 funcall-interactively: Wrong number of arguments: (lambda nil (interactive “p”) (if (use-region-p) (zilongshanren/indent-region 4) (insert " "))), 1 这是为什么?

您的代码非常有用,我想在您的基础上自己修改一下,因为有时候比如在第2列的时候,按tab也会前进4个,其实我希望能对齐在4的位数列上,所以我想请教个问题,就是如何获取到当然光标在第几列,这样我获取到以后算一下,就知道该填充几个空格了。

(current-column)

可以用 C-h f 根据语义模糊搜索你想要的函数