Thư viện để tự động chèn chuỗi python theo kiểu Google


8

Tôi đang tìm kiếm một gói elisp tự động chèn chuỗi doc doc cho một phương thức. Tôi tìm thấy một gói, rất gần với mục đích của tôi. Nhưng đó là trong văn bản được cấu trúc lại, không phải theo phong cách Google.

nhân sư-doc.el https://github.com/naiquevin/sphinx-doc.el

Mô tả các đối số trong tài liệu (hướng dẫn kiểu python của Google) https://www.chromium.org/chromium-os/python-style-guferences#TOC-Descriping-argument-in-docstrings

Kỳ vọng của tôi là khi tôi gọi M-x sphinx-doc-googletrong hàm sau,

def some_function(a, b, c):

Tôi cần một kết quả như thế này.

def some_function(a, b, c):
    """
    Args:
        a:
        b:
        c:
    Returns:
    """

Tôi biết nó không khó để tự thực hiện. Tôi chỉ muốn hỏi câu hỏi này để tránh sự tái phát minh.


Tôi không nghĩ là có. Phong cách này không thực sự phổ biến trong cộng đồng Python lớn hơn như tôi biết.
lunaryorn

Cảm ơn. Tôi nghĩ nó phổ biến vì cài đặt mặc định của quy tắc chèn chuỗi tự động của PyCharm là kiểu Google. Tôi đã sử dụng văn bản tái cấu trúc trong một thời gian, nhưng nó không dễ đọc cho lắm. :(
sy2

Câu trả lời:


8

Tôi sử dụng gói được gọi là yasnippet cho một cái gì đó tương tự như thế này. Sau một số thay đổi nhỏ, tôi đã điều chỉnh nó để sử dụng kiểu tài liệu Google thay thế:

Google theo kiểu yasnippet

Tuy nhiên, lưu ý rằng nó yêu cầu một số thiết lập:

Đoạn mã cần thực thi một số mã elisp tiện ích để tạo văn bản. Điều này thường được giải quyết bằng cách tạo một tệp được gọi .yas-setup.elvới mã bên trong python-modethư mục đoạn trích. Tuy nhiên, cũng có thể đặt mã ở đâu đó bên trong của bạn .emacs.

Mã cho đoạn mã là:

# -*- mode: snippet -*-
# Insert Google style docstring and function definition.
# name: Python Google style Docstring
# key: defg
# type: snippet
# contributor: Xaldew
# --
def ${1:name}($2):
    \"\"\"$3
    ${2:$(python-args-to-google-docstring yas-text t)}
    ${5:Returns:
        $6
}
    \"\"\"
    ${0:$$(let ((beg yas-snippet-beg)
                (end yas-snippet-end))
        (yas-expand-snippet
          (buffer-substring-no-properties beg end) beg end
              (quote ((yas-indent-line nil) (yas-wrap-around-region nil))))
            (delete-trailing-whitespace beg (- end 1)))}

Mã cho .yas-setup.el:

(defun python-args-to-google-docstring (text &optional make-fields)
  "Return a reST docstring format for the python arguments in yas-text."
  (let* ((indent (concat "\n" (make-string (current-column) 32)))
         (args (python-split-args text))
     (nr 0)
         (formatted-args
      (mapconcat
       (lambda (x)
         (concat "   " (nth 0 x)
             (if make-fields (format " ${%d:arg%d}" (cl-incf nr) nr))
             (if (nth 1 x) (concat " \(default " (nth 1 x) "\)"))))
       args
       indent)))
    (unless (string= formatted-args "")
      (concat
       (mapconcat 'identity
          (list "" "Args:" formatted-args)
          indent)
       "\n"))))

Lưu ý rằng python-split-argsđược cung cấp bởi các đoạn tiêu chuẩn . Tức là: https://github.com/AndreaCrotti/yasnippet-snippets/tree/master Tuy nhiên, bạn nhận được những thứ đó theo mặc định khi bạn cài đặt gói thông qua package.el.

Với mọi thứ được thiết lập đúng, bạn sẽ có thể viết "defg" theo sau Tabđể mở rộng đoạn trích (Xem hình ảnh để biết ví dụ).

Vẫn còn một vấn đề với việc sử dụng điều này bên trong thụt lề lồng nhau, ví dụ, trong các lớp hoặc như các hàm lồng nhau. Trong những trường hợp đó, chuỗi doc bị sai lệch thụt vào một thời gian thêm vì một số lý do. Tôi sẽ cập nhật bài viết này nếu tôi quản lý để sửa nó.

Đoạn mã bây giờ sẽ hoạt động bên trong các phạm vi khác bằng cách cấm yasnippettự động thụt vào bản mở rộng thứ hai.


Câu hỏi ngu ngốc, nhưng làm thế nào để tôi thực sự làm việc này trên một chức năng hiện có? Tôi gõ defgvà nó cung cấp cho tôi một hàm mới có tên namekhông có đối số và tôi không thể thấy bất kỳ cách nào để tự động hóa nó cập nhật chuỗi doc khi tôi thay đổi hàm đó. Khi tôi nhìn vào bộ đệm Tin nhắn của tôi, tôi thấy yas--update-mirrors: Wrong type argument: stringp, (python-args-to-google-docstring).
Autumnsault

1
Tôi thực sự đã gặp điều này ngày hôm nay cũng như trong một đoạn khác của tôi, tôi nghĩ rằng nó có thể là một lỗi trong yasnippet. Tôi sẽ phải tạo một ví dụ tối thiểu để báo cáo đúng. Nó cũng có thể là các đoạn chuỗi trong thời trang này không còn được hỗ trợ nữa, nhưng tôi hy vọng đó không phải là nó.
Xaldew

Đây vẫn là một vấn đề? Tôi không còn có thể sao chép lỗi trên bằng cách sử dụng Emacs / yasnippet mới nhất.
Xaldew

Vâng, nó vẫn có vấn đề. Tôi đang sử dụng emacs 24.5.1 (phiên bản Ubuntu mới nhất) và phiên bản mới nhất của yasnippet.
Autumnsault

1
@AstroFloyd Đúng vậy, mã cho .yas-setup.elcuối cùng sẽ nằm trong cùng thư mục với thư mục đoạn mã cho chế độ hiện đang hoạt động. Đó là ~/.emacs.d/snippets/python-mode/.yas-setup.elcho chế độ python như bạn đã chỉ ra.
Xaldew

3

Như lunaryorn đã đề cập rằng phong cách không phổ biến và không có gói nào.

Tuy nhiên, có một gói được gọi là sphinx-doc sẽ tạo chuỗi doc ở định dạng nhân sư ( bản demo ).

Bạn có thể sửa đổi gói đó để tạo chuỗi theo yêu cầu của bạn.


-1

Bạn có thể sử dụng mã này.

Di chuyển con trỏ trên tên hàm của bạn và sau đó F9.

 (defun chomp (str)
        "Chomp leading and tailing whitespace from STR."
        (let ((s (if (symbolp str) (symbol-name str) str)))
          (replace-regexp-in-string
           "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" "" s)))
 (defun get-function-definition(sentence)
    (if (string-match "def.*(.*):" sentence)
        (match-string 0 sentence)))
 (defun get-parameters(sentence)
    (setq y (get-function-definition sentence))
    (if y
        (if (string-match "(.*)" y)
            (match-string 0 y))))
 (autoload 'thing-at-point "thingatpt" nil t) ;; build-in librairie
 (defun python-insert-docstring()
        (interactive)
        (setq p (get-parameters (thing-at-point 'sentence)))
        (forward-line 1)
        (insert "    \"\"\"\n")
        (insert "\tArgs:\n")
        (setq params (split-string p "[?\,?\(?\)?\ ]"))
        (while params
          (if (/= (length (chomp (car params))) 0)
              (progn
                (insert "        ")
                (insert (chomp (car params)))
                (insert ": \n")))
          (setq params (cdr params)))
        (insert "    Returns:\n    \"\"\"\n"))
      (global-set-key (kbd "<f9>") 'python-insert-docstring)
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.