Di chuyển biểu mẫu lên và xuống trên chế độ paredit


13

Tôi đã sử dụng Chỉnh sửa cấu trúc của chữ thảo (chế độ giống như paredit cho Intellij và Cursive) và tôi đã tìm thấy một lệnh hay ở đó gọi là di chuyển lên (và xuống).

Di chuyển hình thức lên làm điều này ( |là điểm):

(+ 1 |(+ 2 3) 4) => (+ (+ 2 3) 1 4)

và Di chuyển xuống dưới là tương tự:

(+ 1 |(+ 2 3) 4) => (+ 1 4 (+ 2 3))

Có thể làm điều này trên chế độ paredit Emacs? Tôi nghĩ rằng nó không có trên bộ paredit cơ bản (ít nhất là nó không được mô tả trên tờ cheat này


Đẹp. Bây giờ đó là một hoạt động tôi có thể thấy bản thân mình đang làm.
PythonNut

2
FWIW, ít nhất là trong hai ví dụ bạn trình bày, rõ ràng C-M-tvề cùng một điều. Nhưng tôi đoán những gì bạn có nghĩa là hình thức tương tự tiếp tục được di chuyển, thay vì có sự thay đổi tiến trình sang cặp giới tính tiếp theo.
vẽ

Câu trả lời:


13

Như @Drew đề xuất, C-M-tlàm những gì bạn muốn. Quy tắc là như thế này:

  • Đặt điểm ở giữa hai sexps.
  • Nhấn C-M-t(mà chạy transpose-sexp).
  • Các sexp trái luôn luôn di chuyển sang bên phải cùng với điểm. Điều này rất quan trọng , nếu không bạn sẽ bối rối đến tận cùng.

Hoặc, bạn có thể nghĩ đơn giản rằng đây không phải là hoán vị mà chỉ đơn giản là để tiến về phía trước, bạn phải đặt điểm sau khi sexp bạn muốn di chuyển.

Tuy nhiên, có một điều tiện lợi là, khi bạn muốn chuyển đổi giới tính trái về phía sau, bạn sử dụng tương tự C-M-tnhưng được cung cấp với một đối số tiền tố phủ định và điều này bất tiện. Một vấn đề khác là điểm sẽ không tuân theo giới tính trái được chuyển đổi lạc hậu . Để giải quyết vấn đề này, chúng tôi tạo một phiên bản ngược của transpose-sexps:

(defun reverse-transpose-sexps (arg)
  (interactive "*p")
  (transpose-sexps (- arg))
  ;; when transpose-sexps can no longer transpose, it throws an error and code
  ;; below this line won't be executed. So, we don't have to worry about side
  ;; effects of backward-sexp and forward-sexp.
  (backward-sexp (1+ arg))
  (forward-sexp 1))

Sau đó, liên kết nó với C-M-ybên cạnh C-M-tvà miễn phí trong Emacs mặc định.

(global-set-key (kbd "C-M-y") 'reverse-tranpose-sexps)

Đây là một bản demo; bạn sẽ nhận thấy rằng (MY-SEXP1)ở bên trái tất cả thời gian để được di chuyển tiến / lùi:

nhập mô tả hình ảnh ở đây


5

Có thể làm điều đó với lispy , một hình thức tiên tiến paredit-mode.

Đối với trường hợp sử dụng của bạn:

  • w di chuyển lên
  • s di chuyển xuống

Điều duy nhất là con trỏ phải ở trạng thái ngang nhau, đó là trong ví dụ của bạn:

(+ 1 |(+ 2 3) 4)

Bạn cũng có thể di chuyển nhiều sexps cùng một lúc ws, nếu bạn đánh dấu chúng bằng một vùng. Xem tài liệu để biết thêm.


;; Có cách nào để chỉ sử dụng hai lệnh đó không? ;; Tôi dường như mất "M-left" và "M-right" khi làm như vậy: `(add-hook 'clojure-mode-hook (lambda () (lispy-mode 1) (local-set-key (kbd" M - <up> ") 'lispy-move-up) (local-set-key (kbd" M- <down> ")' lispy-move-down)))
nha

1

Đây là một lệnh khác (từ thư viện misc-cmds.el) thực hiện khá nhiều những gì bạn yêu cầu. Chỉ cần liên kết nó với một khóa duy nhất ( C-M-thoặc bất cứ điều gì). Sử dụng nó để di chuyển một sexp cả về phía trước và phía sau nhiều lần.

Một tiền tố phủ định chuyển đổi ngược, giống như transpose-sexp, nhưng nó cũng để lại điểm sẵn sàng để thực hiện một chuyển vị ngược khác. Và khi lặp lại, một tiền tố phủ định arg chỉ lật hướng.

Vì vậy, nếu bạn liên kết lệnh với, giả sử, C-osau đó di chuyển sexp ở bên trái của điểm sang bên phải ba lần, sau đó sang bên trái hai lần, sau đó sang bên phải một lần.C-o C-o C-o C-- C-o C-o C-- C-o

Một tiền tố số arg chỉ có tác dụng cho lần sử dụng đầu tiên, nghĩa là, không phải khi lặp lại - khi lặp lại, chuyển động luôn luôn là một sexp mỗi lần.

(defun reversible-transpose-sexps (arg)
  "Reversible and repeatable `transpose-sexp'.
Like `transpose-sexps', but:
 1. Leaves point after the moved sexp.
 2. When repeated, a negative prefix arg flips the direction."
  (interactive "p")
  (when (eq last-command 'rev-transp-sexps-back) (setq arg  (- arg)))
  (transpose-sexps arg)
  (unless (natnump arg)
    (when (or (> emacs-major-version 24)
              (and (= emacs-major-version 24)  (> emacs-minor-version 3)))
      (backward-sexp (abs arg)) (skip-syntax-backward " ."))
    (setq this-command  'rev-transp-sexps-back)))

(Lưu ý: Hành vi transpose-sexpsđã thay đổi trong 24.4, do đó kiểm tra phiên bản tại đây. Trước ngày 24.4, điểm kết thúc ở đúng nơi để tiếp tục (ví dụ: lặp lại). Bắt đầu từ 24.4, điểm nằm ở vị trí sai cho điều đó. hồi quy hoặc thêm một tính năng hữu ích hoặc sửa một số lỗi khác có lẽ nằm trong mắt của kẻ si tình. ;-) Tôi đã nộp lỗi Emacs # 20698 cho việc này, ngay bây giờ.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.