Emacs thụt lề số lượng lớn cho Python


132

Làm việc với Python trong Emacs nếu tôi muốn thêm một lần thử / ngoại trừ một khối mã, tôi thường thấy rằng tôi phải thụt toàn bộ khối, từng dòng một. Trong Emacs, làm thế nào để bạn thụt toàn bộ khối cùng một lúc.

Tôi không phải là người dùng Emacs có kinh nghiệm, nhưng chỉ thấy đó là công cụ tốt nhất để làm việc thông qua ssh. Tôi đang sử dụng Emacs trên dòng lệnh (Ubuntu), không phải là gui, nếu điều đó tạo ra sự khác biệt.


5
C-c >cho đúng C-c <cho bên trái
Thamme Gowda

Câu trả lời:


213

Nếu bạn đang lập trình Python bằng Emacs, thì có lẽ bạn nên sử dụng chế độ python. Với chế độ python, sau khi đánh dấu khối mã,

C-c >hoặc C-c C-l dịch chuyển vùng 4 không gian sang phải

C-c <hoặc C-c C-r dịch chuyển vùng 4 không gian sang trái

Nếu bạn cần thay đổi mã theo hai mức độ lưu ý hoặc một số lượng tùy ý, bạn có thể thêm tiền tố vào lệnh bằng một đối số:

C-u 8 C-c > dịch chuyển vùng 8 không gian sang phải

C-u 8 C-c < dịch chuyển vùng 8 không gian sang trái

Một cách khác là sử dụng M-x indent-rigidlymà ràng buộc với C-x TAB:

C-u 8 C-x TAB dịch chuyển vùng 8 không gian sang phải

C-u -8 C-x TAB dịch chuyển vùng 8 không gian sang trái

Cũng hữu ích là các lệnh hình chữ nhật hoạt động trên hình chữ nhật của văn bản thay vì dòng văn bản.

Ví dụ: sau khi đánh dấu một vùng hình chữ nhật,

C-x r o chèn khoảng trống để điền vào vùng hình chữ nhật (chuyển mã hiệu quả sang phải)

C-x r k Giết vùng hình chữ nhật (chuyển mã hiệu quả sang trái)

C-x r tnhắc nhở một chuỗi để thay thế hình chữ nhật với. Nhập C-u 8 <space>sau đó sẽ nhập 8 khoảng trắng.

Tái bút Với Ubuntu, để biến chế độ python thành chế độ mặc định cho tất cả các tệp .py, chỉ cần cài đặt python-modegói.


Cảm ơn rằng hoạt động hoàn hảo. với Emacs22 không phải chế độ python tự động được bật với tất cả các tệp .py? Dù sao, Cc> hoạt động tốt.
Vernon

@Vernon: C-c >được định nghĩa trong python-mode.el, vì vậy tôi nghĩ rằng bạn phải cài đặt python-modegói ở đâu đó trên đường đi. Vui mừng nó làm việc cho bạn.
unutbu

1
Cc> hoạt động tốt trong Emacs 23.2 mà không cần cài đặt chế độ python vì nó hoạt động với python.el
codeasone

@landstatic: Cảm ơn thông tin. Điều đó khiến tôi nghĩ có lẽ tất cả các lệnh được liệt kê ở trên đều hoạt động giống nhau đối với python-mode.el hoặc python.el?
unutbu

2
@redobot: C-c C-lC-c C-rphải là các ràng buộc tùy chỉnh mà bạn tự thiết lập. Nếu bạn chạy emacs -q(để chạy emacs mà không tải tệp init), bạn sẽ thấy không có ràng buộc nào cho C-c C-lhoặc C-c C-rtrong chế độ Python.
unutbu

9

Ngoài ra indent-region, được ánh xạ tới C-M-\theo mặc định, các lệnh chỉnh sửa hình chữ nhật rất hữu ích cho Python. Đánh dấu một khu vực như bình thường, sau đó:

  • C-x r t( string-rectangle): sẽ nhắc bạn về các ký tự bạn muốn chèn vào từng dòng; tuyệt vời để chèn một số lượng không gian nhất định
  • C-x r k( kill-rectangle): xóa vùng hình chữ nhật; tuyệt vời để loại bỏ vết lõm

Bạn cũng có thể C-x r y( yank-rectangle), nhưng điều đó hiếm khi hữu ích.


4

indent-regionánh xạ để C-M-\làm các thủ thuật.


3
Đây là lời khuyên khủng khiếp. Không thể suy ra thụt Python (vì nó là cú pháp!) Nên vùng nhận dạng là vô dụng.
Sam Clearman

1

Tôi đã sử dụng chức năng này để xử lý sự thụt lề và không cố định của mình:

(defun unindent-dwim (&optional count-arg)
  "Keeps relative spacing in the region.  Unindents to the next multiple of the current tab-width"
  (interactive)
  (let ((deactivate-mark nil)
        (beg (or (and mark-active (region-beginning)) (line-beginning-position)))
        (end (or (and mark-active (region-end)) (line-end-position)))
        (min-indentation)
        (count (or count-arg 1)))
    (save-excursion
      (goto-char beg)
      (while (< (point) end)
        (add-to-list 'min-indentation (current-indentation))
        (forward-line)))
    (if (< 0 count)
        (if (not (< 0 (apply 'min min-indentation)))
            (error "Can't indent any more.  Try `indent-rigidly` with a negative arg.")))
    (if (> 0 count)
        (indent-rigidly beg end (* (- 0 tab-width) count))
      (let (
            (indent-amount
             (apply 'min (mapcar (lambda (x) (- 0 (mod x tab-width))) min-indentation))))
        (indent-rigidly beg end (or
                                 (and (< indent-amount 0) indent-amount)
                                 (* (or count 1) (- 0 tab-width))))))))

Và sau đó tôi gán nó cho một phím tắt:

(global-set-key (kbd "s-[") 'unindent-dwim)
(global-set-key (kbd "s-]") (lambda () (interactive) (unindent-dwim -1)))

1

Tôi là một người mới của Emacs, vì vậy câu trả lời này có lẽ giáp với vô dụng.

Không có câu trả lời nào được đề cập cho đến nay bao gồm việc thụt lại các chữ như dicthoặc list. Ví dụ M-x indent-regionhay M-x python-indent-shift-rightvà công ty sẽ không giúp đỡ nếu bạn đã cắt-và-dán đen sau và cần nó để được tái thụt vào một cách hợp lý:

    foo = {
  'bar' : [
     1,
    2,
        3 ],
      'baz' : {
     'asdf' : {
        'banana' : 1,
        'apple' : 2 } } }

Cảm giác như M-x indent-regionnên làm điều gì đó hợp lý python-mode, nhưng đó không phải là (chưa).

Đối với trường hợp cụ thể trong đó chữ của bạn được đặt trong ngoặc, sử dụng TAB trên các dòng trong câu hỏi sẽ đạt được những gì bạn muốn (vì khoảng trắng không đóng vai trò).

Vì vậy, những gì tôi đã làm trong những trường hợp như vậy là một cách nhanh chóng ghi âm một vĩ mô bàn phím như <f3> C-n TAB <f4>như trong F3, Ctrl-n (hoặc xuống mũi tên), TAB, F4, và sau đó sử dụng F4 nhiều lần để áp dụng các vĩ mô có thể tiết kiệm một vài tổ hợp phím. Hoặc bạn có thể làm C-u 10 C-x eđể áp dụng nó 10 lần.

(Tôi biết nó không có vẻ nhiều, nhưng hãy thử thụt lại 100 dòng rác theo nghĩa đen mà không bỏ lỡ mũi tên xuống, và sau đó phải đi lên 5 dòng và lặp lại mọi thứ;)).


1

Tôi sử dụng đoạn mã sau. Trên tab khi lựa chọn không hoạt động, nó thụt dòng hiện tại (như bình thường); khi lựa chọn không hoạt động, nó thụt vào toàn bộ khu vực bên phải.

(defun my-python-tab-command (&optional _)
  "If the region is active, shift to the right; otherwise, indent current line."
  (interactive)
  (if (not (region-active-p))
      (indent-for-tab-command)
    (let ((lo (min (region-beginning) (region-end)))
          (hi (max (region-beginning) (region-end))))
      (goto-char lo)
      (beginning-of-line)
      (set-mark (point))
      (goto-char hi)
      (end-of-line)
      (python-indent-shift-right (mark) (point)))))
(define-key python-mode-map [remap indent-for-tab-command] 'my-python-tab-command)

1

Làm thụt tương tác.

  1. Chọn khu vực được thụt lề.
  2. Cx TAB.
  3. Sử dụng mũi tên ( <-->) để thụt lề tương tác.
  4. Nhấn Escba lần khi bạn thực hiện với thụt đầu dòng cần thiết.

Sao chép từ bài viết của tôi trong: Ấn định vài dòng trong Emacs


-2

Tôi làm một cái gì đó như thế này

;; intent whole buffer 
(defun iwb ()
  "indent whole buffer"
  (interactive)
  ;;(delete-trailing-whitespace)
  (indent-region (point-min) (point-max) nil)
  (untabify (point-min) (point-max)))

2
Vì khoảng trắng là một phần của cú pháp trong Python, vùng thụt lề trên toàn bộ tệp là một ý tưởng tồi.
Daniel Stutzbach
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.