在 emacs 中移动区域或行

问题描述 投票:0回答:4

我正在 emacs 中寻找一种将文本向右或向左移动

n
空格的方法。与 vim
<<
>>
中的功能类似。它应该在一个区域上工作,或者如果当前行上没有选择任何区域,并且不会将光标从当前位置移动。

来自 EmacsWiki 的解决方案并不像

M-x indent-rigidly
那样工作得很好,因为它会记住最后使用的区域并转移该区域。最接近的似乎是here,但我没能成功。我不是 Lisp 开发人员,因此很难修改代码。我将不胜感激任何帮助。

谢谢!

emacs indentation text-manipulation
4个回答
40
投票

您可以选择区域,然后

C-u C-x <tab>
将移动4个空格。您可以在 C-u 后面输入一个数字,将 4 更改为其他任何值。


9
投票

也许这会按照你想要的方式工作。

(defun 移位文本(距离)
  (如果(使用区域-p)
      (让((标记(标记)))
        (保存游览
          (严格缩进(区域开始)
                          (区域结束)
                          距离)
          (推标记 t t)
          (setq 停用-标记为零)))
    (严格缩进(行开始位置)
                    (线端位置)
                    距离)))

(defun 右移(计数)
  (交互式“p”)
  (移位文本计数))

(defun 左移(计数)
  (交互式“p”)
  (移位文本(- 计数)))

6
投票

为了实现这一目标,我通常会使用一个技巧:

  • 激活CUA模式
  • 转到行首
  • C-RET,现在如果你移动光标,你应该看到一个矩形红色区域
  • 将光标向下移动并键入空格,直到获得正确的移位。

这也可以通过某种方式以编程方式完成(以相同的方式)。

编辑: 我刚刚读过 emacs wiki 中的文章,它是相同的解决方案,除了 CUA 模式,它比“常见”矩形选择(因为它是可视的)更强大。


1
投票

当我使用Evil(与Doom Emacs)时,类似Vim的区域移动已经在邪恶的视觉模式中通过S-v</>正确实现。

不过,我主要使用

insert-mode
,当它处于活动状态时,我也希望能够移动区域,最好是通过当前语言的
shift-width

为了实现这一目标,这里有一个实现,重新使用邪恶的转移,但在

insert-mode
中“正确”地实现了。

(defun jj/shift-text (beg end shift-block-fun shift-line-fun)
  "shift text in region or line using evil like S-v with < and > do in Vim.
  It takes special care of preserving or even extending the region to the moved text lines."
  (if (use-region-p)
      (progn
        (let ((point-at-end (< (mark) (point))))

          ;; fix up current region end to grab the whole line
          (if point-at-end
              (end-of-line)
            (beginning-of-line))

          ;; then fix up the other region end
          (exchange-point-and-mark)
          (if point-at-end
              (beginning-of-line)
            (end-of-line))

          ;; restore mark-point order
          (exchange-point-and-mark)

          (let ((linebeg (if point-at-end (mark) (point)))
                (lineend (if point-at-end (point) (mark))))
            ;; shift the text
            (save-mark-and-excursion
              (funcall shift-block-fun linebeg lineend)
              ;; "In Transient Mark mode, every buffer-modifying primitive sets deactivate-mark"
              ;; but we wanna keep it active :)
              (setq deactivate-mark nil)))))

    (funcall shift-line-fun 1)))

(defun jj/shift-left (beg end)
  (interactive "r")
  (jj/shift-text beg end #'evil-shift-left #'evil-shift-left-line))

(defun jj/shift-right (beg end)
  (interactive "r")
  (jj/shift-text beg end #'evil-shift-right #'evil-shift-right-line))

以及定义键绑定的位置:

  ;; text shifting. evil-normal-state-map has these anyway.
  (define-key evil-hybrid-state-map (kbd "M-<") #'jj/shift-left)
  (define-key evil-hybrid-state-map (kbd "M->") #'jj/shift-right)
© www.soinside.com 2019 - 2024. All rights reserved.