请问如何让<backspace>删除到这一行的缩进位置?

大约是这么个意思,试了很多插件和代码都没法做到,各位有简单的解决方法吗。 其他的回退行为都是正常的,比如 str |ing这样的

int main() {
     printf("Hello, World!\n")
         
                             |    
     return 0;
}
按下<backspace>
int main() {
     printf("Hello, World!\n");
    
    |
     return 0;
}
按下<backspace>
int main() {
     printf("Hello, World!\n");
    |
     return 0;
}
按下<backspace>
int main() {
     printf("Hello, World!\n");|
     return 0;
}
把光标移到行首
int main() {
    |printf("Hello, World!\n");
     return 0;
}
再次按下<backspace>
int main() {|printf("Hello, World!\n");
     return 0;
}

也有这种情况,总之就是删除到这一行的缩进位置,这个位置由此行上面的非空行提供

int main() {
     printf("Hello, World!\n")
    p
                   |
     return 0;
}
按下<backspace>
int main() {
     printf("Hello, World!\n");
    p
   |
     return 0;
}
(global-set-key (kbd "<backspace>") (lambda ()
                                        (interactive)
                                        (kill-line 0)
                                        (indent-according-to-mode)))

这段代码目前可以做到

int main() {
     printf("Hello, World!\n")
         
                             |    
     return 0;
}
按下<backspace>
int main() {
     printf("Hello, World!\n");
    
    |
     return 0;
}
1 个赞

其实就是 Intellij 系列 IDE 的默认行为,分享一下我的方案,适用于各种模式:

(defun intellij-backspace (arg)
  (interactive "*P")
  (if (or (region-active-p) (not (looking-back "^[[:space:]]*" (line-beginning-position))))
      (backward-delete-char-untabify (prefix-numeric-value arg))
    (let* ((beg (point))
           (end (progn (indent-for-tab-command) (point))))
      (when (<= beg end)
        (if (save-excursion (forward-line -1) (line-blank-p))
            (progn (delete-region (line-beginning-position 0) (line-beginning-position)) (back-to-indentation))
          (delete-indentation))))))

(defun line-blank-p ()
  (save-excursion
    (beginning-of-line)
    (looking-at "[[:space:]]*$")))

Kooha-02-24-2022-00-05-57

4 个赞

请教一下,在绑定到 <backspace> 后在 minibuffer 里删除字符会有错误出现

read-from-minibuffer: Wrong type argument: commandp, kill-chararcter-or-empty-line-and-keep-inden [8 times]

绑定后我这minibuffer里不会报这个错

你可以试下只绑定到prog-mode-map,这样就不会影响到minibuffer了。

(define-key prog-mode-map (kbd "<backspace>") #'intellij-backspace)
1 个赞

啊哈,感谢!

我之前弄了一个只适用于c的版本

(defun clion-backspace ()
  (interactive)
  (if (or
       (> (current-column) (current-indentation))
       (use-region-p)
       current-prefix-arg)
      (call-interactively  #'c-electric-backspace)
    (if (bolp)
	(when (plb) (c-indent-line))
      (when (= (c-indent-line) 0) (plb)))))

(defun plb ()
  (if (save-excursion
	(forward-line -1)
	(looking-at-p "[[:space:]]*$"))
      (null (delete-region
	     (line-beginning-position 0)
	     (line-beginning-position)))
    (delete-indentation)))

(indent-for-tab-command) 是比较通用的缩进命令,用它可以免去对不同 major-mode 单独的适配

好的,我试试

cool~~~