将Python模式与Emacs中的Org模式相结合

10
我将org-mode和lisp-mode结合,以实现在emacs中针对lisp代码的美丽代码折叠: lisp-orgi-mode。基本上,我使用';'而不是'*'作为标题字符。 对于注释,我只需在';'前面加一个空格,使其成为' ;',这样它就不会被视为标题...
然而,用python-mode做同样的事情却行不通... 可能是因为Python注释使用的'#'字符与org-mode设置产生了冲突...
有人能够成功地将这些功能组合起来吗? 我知道有人已经将python-mode与outline-mode (链接)组合起来,但ouline-mode并不像org-mode那样好用...
编辑:通过outline-magic,我成功地使其与python-magic.el良好地配合。
3个回答

9
我使用 hideshow-org这里有一个简短的介绍)来实现此目的,我认为它非常好用。
以下是一些额外但有用的代码片段:
(dolist (hook (list 'c-mode-common-hook
            'emacs-lisp-mode-hook
            'java-mode-hook
            'lisp-mode-hook
            'perl-mode-hook
            'sh-mode-hook))
  (add-hook hook 'my-hideshow-hook))

(defun my-hideshow-hook ()
  "thisandthat."
  (interactive)
  (progn (require 'hideshow-org)
     (global-set-key (kbd "C-c h") 'hs-org/minor-mode)
     (hs-org/minor-mode)))

(defadvice goto-line (after expand-after-goto-line activate compile)
  "hideshow-expand affected block when using goto-line in a collapsed buffer"
  (save-excursion
    (hs-show-block)))

很好。是否可以在一个迭代之外循环折叠级别? - Naveen
不,它并不像org-mode那样好,可以循环不同的折叠级别。但它仍然非常有用,比<kbd>C-x n n</kbd>快得多。 - monotux
以下解决方案可以像org-mode一样循环不同的折叠级别。你试过了吗? - Naveen
不,我还没有尝试下面的代码。上面的代码几乎适用于任何语言(lisp、java、python...),具有相同的功能,这非常好。 - monotux

6

好的,我已经成功地使用以下outline-regexp将outline-minor-mode运行得很好: "[ \t]*# \|[ \t]+\(class\|def\|if\|elif\|else\|while\|for\|try\|except\|with\) "现在,我可以使用python语法和注释行作为标题来折叠代码。
是否有可能修改您的代码以使用选项卡调用'indent-for-tab-command,如果没有要执行的操作,则调用'outline-cycle?

python-magic.el :

; 需要CarstenDominik在此处找到的outline-magic.el:http://www.astro.uva.nl/~dominik/Tools/outline-magic.el
; Nikwin稍微修改了这里的代码:https://dev59.com/UnNA5IYBdhLWcg3wH6AW#1085551
(add-hook 'outline-minor-mode-hook (lambda () (require 'outline-magic) )) (add-hook 'python-mode-hook 'my-python-outline-hook)
(defun py-outline-level () (let (buffer-invisibility-spec) (save-excursion (skip-chars-forward " ") (current-column))))
(defun my-python-outline-hook () (setq outline-regexp "[ \t]*# \\|[ \t]+\\(class\\|def\\|if\\|elif\\|else\\|while\\|for\\|try\\|except\\|with\\) ") (setq outline-level 'py-outline-level)
(outline-minor-mode t) (hide-body) (show-paren-mode 1) (define-key python-mode-map [tab] 'outline-cycle) (define-key outline-minor-mode-map [S-tab] 'indent-for-tab-command) (define-key outline-minor-mode-map [M-down] 'outline-move-subtree-down) (define-key outline-minor-mode-map [M-up] 'outline-move-subtree-up) ) (provide 'python-magic)

1

我认为outline-magic已被outshine取代,但我不知道上面的代码是否适用于它。但是我通过Ryan Davis的博客文章成功地运行了以下代码:

(defun python-mode-outline-hook ()
  (setq outline-level 'python-outline-level)

  (setq outline-regexp
    (rx (or
         ;; Commented outline heading
         (group
          (* space)  ; 0 or more spaces
          (one-or-more (syntax comment-start))
          (one-or-more space)
          ;; Heading level
          (group (repeat 1 8 "\*"))  ; Outline stars
          (one-or-more space))

         ;; Python keyword heading
         (group
          ;; Heading level
          (group (* space)) ; 0 or more spaces
          bow
          ;; Keywords
          (or "class" "def" "else" "elif" "except" "for" "if" "try" "while")
          eow)))))

(defun python-outline-level ()
  (or
   ;; Commented outline heading
   (and (string-match (rx
               (* space)
               (one-or-more (syntax comment-start))
               (one-or-more space)
               (group (one-or-more "\*"))
               (one-or-more space))
              (match-string 0))
    (- (match-end 0) (match-beginning 0)))

   ;; Python keyword heading, set by number of indentions
   ;; Add 8 (the highest standard outline level) to every Python keyword heading
   (+ 8 (- (match-end 0) (match-beginning 0)))))

(add-hook 'python-mode-hook 'python-mode-outline-hook)

也许有人会觉得这很有用。我认为这是一种使编辑和导航代码更容易的惊人方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接