【问题标题】:Emacs Shift-Tab to left shift the blockEmacs Shift-Tab 左移块
【发布时间】:2010-02-12 05:59:35
【问题描述】:

如何让 Emacs 以 ShiftTab 将所选文本向左移动 4 个空格?

【问题讨论】:

    标签: emacs


    【解决方案1】:

    为此,我使用命令indent-rigidly,绑定到C-x TAB。给它参数 -4 将所选区域向左移动四个空格:C-u -4 C-x TAB

    http://www.gnu.org/s/emacs/manual/html_node/elisp/Region-Indent.html

    【讨论】:

    • 对于相同的手动输入,您可能更喜欢indent-code-rigidly,因为它只保留了 cmets 和多行字符串
    【解决方案2】:

    这会从当前行的前面删除 4 个空格(前提是空格存在)。

    (global-set-key (kbd "<S-tab>") 'un-indent-by-removing-4-spaces)
    (defun un-indent-by-removing-4-spaces ()
      "remove 4 spaces from beginning of of line"
      (interactive)
      (save-excursion
        (save-match-data
          (beginning-of-line)
          ;; get rid of tabs at beginning of line
          (when (looking-at "^\\s-+")
            (untabify (match-beginning 0) (match-end 0)))
          (when (looking-at "^    ")
            (replace-match "")))))
    

    如果您的变量 tab-width 恰好是 4(这就是您想要“撤消”的内容),那么您可以将 (looking-at "^ ") 替换为更通用的名称,例如 (concat "^" (make-string tab-width ?\ ))

    此外,代码将使用untabify 将行前的制表符转换为空格。

    【讨论】:

    • 不错!但我会使用 WHEN 而不是 IF,因为没有 else 子句。
    • 对我来说,它不适用于选定的区域。只有第一行:-/
    • @Mauricio A. Cinelli -- 绑定到 (kbd "&lt;backtab&gt;") 而不是 (kbd "&lt;S-tab&gt;") 对我有用。
    【解决方案3】:

    我制作了一些函数,根据您使用的是 tab 还是 shift+tab,将一个区域向左或向右移动四个空格:

    (defun indent-region-custom(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 untab-region (N)
        (interactive "p")
        (indent-region-custom -4)
    )
    
    (defun tab-region (N)
        (interactive "p")
        (if (active-minibuffer-window)
            (minibuffer-complete)    ; tab is pressed in minibuffer window -> do completion
        ; else
        (if (string= (buffer-name) "*shell*")
            (comint-dynamic-complete) ; in a shell, use tab completion
        ; else
        (if (use-region-p)    ; tab is pressed is any other buffer -> execute with space insertion
            (indent-region-custom 4) ; region was selected, call indent-region-custom
            (insert "    ") ; else insert four spaces as expected
        )))
    )
    
    (global-set-key (kbd "<backtab>") 'untab-region)
    (global-set-key (kbd "<tab>") 'tab-region)
    

    编辑:添加了 Maven 的代码来检查是否在 minibuffer 中,以及在特定缓冲区(例如 shell)中的 tab 补全。

    【讨论】:

    • 很好,接受的答案仅适用于 1 行,不适用于区域
    • 完美。适用于区域和线路。复制其他常用编辑器的功能。
    【解决方案4】:

    我改进了 Stanley Bak 的回答。 对我来说,这个全局键绑定破坏了 minibuffer 的完成。

    所以我也包含了一个小型缓冲区的案例。

    编辑:重命名indent-region -> indent-region-custom

    indent-region 与现有命令冲突,并在保存时缩进(保存前挂钩)和其他一些组合键出现错误。

    (defun indent-region-custom(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 untab-region (N)
      (interactive "p")
      (indent-region-custom -4)
      )
    
    (defun tab-region (N)
      (interactive "p")
      (if (active-minibuffer-window)
          (minibuffer-complete)    ; tab is pressed in minibuffer window -> do completion
        (if (use-region-p)    ; tab is pressed is any other buffer -> execute with space insertion
            (indent-region-custom 4) ; region was selected, call indent-region-custom
          (insert "    ") ; else insert four spaces as expected
          )
        )
      )
    
    (global-set-key (kbd "<backtab>") 'untab-region)
    (global-set-key (kbd "<tab>") 'tab-region)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      相关资源
      最近更新 更多