├── .gitignore ├── Cask ├── image ├── helm-pydoc.png └── helm-pydoc-action.png ├── helm-pydoc.py ├── Changes ├── README.md └── helm-pydoc.el /.gitignore: -------------------------------------------------------------------------------- 1 | /.cask/ 2 | *.elc 3 | -------------------------------------------------------------------------------- /Cask: -------------------------------------------------------------------------------- 1 | (source gnu) 2 | (source melpa) 3 | 4 | (package-file "helm-pydoc.el") 5 | -------------------------------------------------------------------------------- /image/helm-pydoc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emacsorphanage/helm-pydoc/HEAD/image/helm-pydoc.png -------------------------------------------------------------------------------- /image/helm-pydoc-action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emacsorphanage/helm-pydoc/HEAD/image/helm-pydoc-action.png -------------------------------------------------------------------------------- /helm-pydoc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | from os.path import basename, splitext 6 | import pkgutil 7 | 8 | myname = (splitext(basename(sys.argv[0])))[0] 9 | modules = [m[1] for m in pkgutil.iter_modules() if m[1] != myname] 10 | modules.append('sys') # builtin module 11 | modules.sort() 12 | 13 | for module in modules: 14 | print(module) 15 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for helm-pydoc.el 2 | 3 | Revision 0.07 2015/09/19 syohex 4 | - Fix virualenv python path on Windows(Thanks alexandre-heaume) 5 | 6 | Revision 0.06 2014/07/02 syohex 7 | - Re-factoring 8 | 9 | Revision 0.05 2014/03/08 syohex 10 | - Switch cl-lib 11 | - Enable lexical binding 12 | 13 | Revision 0.04 2013/12/05 syohex 14 | - Change way of opening source file(Thanks proofit404) 15 | 16 | Revision 0.03 2013/11/19 syohex 17 | - Support virtualenv(Thanks proofit404) 18 | 19 | Revision 0.02 2013/11/06 syohex 20 | - Re-factoring 21 | - Fix python script for PEP8 22 | - Use buffer per module 23 | - Add input history feature 24 | 25 | Revision 0.01 2013/11/06 syohex 26 | - Initial version 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # helm-pydoc.el [![melpa badge][melpa-badge]][melpa-link] [![melpa stable badge][melpa-stable-badge]][melpa-stable-link] 2 | 3 | ## Introduction 4 | `helm-pydoc.el` is pydoc helm interface 5 | 6 | 7 | ## Screenshot 8 | 9 | ![helm-pydoc](image/helm-pydoc.png) 10 | 11 | ![helm-pydoc-action](image/helm-pydoc-action.png) 12 | 13 | 14 | ## Requirements 15 | 16 | * Emacs 24.3 or higher 17 | * helm 1.7.4 or higher 18 | 19 | ## Installation 20 | 21 | You can install `helm-pydoc.el` from [MELPA](https://melpa.org/) with `package.el` 22 | 23 | ``` 24 | M-x package-install helm-pydoc 25 | ``` 26 | 27 | 28 | ## Basic Usage 29 | 30 | #### `helm-pydoc` 31 | 32 | `pydoc` with helm interface 33 | 34 | 35 | ## NOTE 36 | 37 | If you use python 2 and set `python-shell-interpreter` to `"ipython"`, 38 | helm-pydoc.el does not work well. Please use python3 if you set `python-shell-interpreter` 39 | to `"ipython"`. 40 | 41 | ## Customize Variable 42 | 43 | #### `helm-pydoc-virtualenv`(Default `"venv"`) 44 | 45 | Directory name of virtualenv. Use virtualenv `python` if this name directory 46 | is found in this directory hierarchy. 47 | 48 | ## Actions 49 | 50 | * View module document 51 | * View source code 52 | * Import module statement 53 | * import module(Insert marked candidates) 54 | * from module import identifier 55 | * from module import identifier 56 | 57 | 58 | ## Sample Configuration 59 | 60 | ```lisp 61 | (with-eval-after-load "python" 62 | (define-key python-mode-map (kbd "C-c C-d") 'helm-pydoc)) 63 | ``` 64 | 65 | [melpa-link]: https://melpa.org/#/helm-pydoc 66 | [melpa-stable-link]: https://melpa.org/#/helm-pydoc 67 | [melpa-badge]: https://melpa.org/packages/helm-pydoc-badge.svg 68 | [melpa-stable-badge]: https://stable.melpa.org/packages/helm-pydoc-badge.svg 69 | -------------------------------------------------------------------------------- /helm-pydoc.el: -------------------------------------------------------------------------------- 1 | ;;; helm-pydoc.el --- pydoc with helm interface -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2016 by Syohei YOSHIDA 4 | 5 | ;; Author: Syohei YOSHIDA 6 | ;; URL: https://github.com/syohex/emacs-helm-pydoc 7 | ;; Version: 0.07 8 | ;; Package-Requires: ((helm-core "3.6.0") (emacs "24.4")) 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation, either version 3 of the License, or 13 | ;; (at your option) any later version. 14 | 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with this program. If not, see . 22 | 23 | ;;; Commentary: 24 | 25 | ;;; Code: 26 | 27 | (require 'cl-lib) 28 | (require 'helm-core) 29 | (require 'python) 30 | 31 | (defgroup helm-pydoc nil 32 | "Pydoc with helm interface" 33 | :group 'helm) 34 | 35 | (defcustom helm-pydoc-virtualenv "venv" 36 | "Directory name containing virtualenv." 37 | :type 'string) 38 | 39 | (defvar helm-pydoc--collect-command 40 | (if load-file-name 41 | (concat (file-name-directory load-file-name) "helm-pydoc.py") 42 | "helm-pydoc.py")) 43 | 44 | (defun helm-pydoc--python () 45 | (with-helm-current-buffer 46 | (let* ((file (or (buffer-file-name) default-directory)) 47 | (venv (locate-dominating-file file helm-pydoc-virtualenv))) 48 | (if venv 49 | (concat (expand-file-name (file-name-as-directory venv)) 50 | helm-pydoc-virtualenv (if (eq system-type 'windows-nt) 51 | "/Scripts/python" 52 | "/bin/python")) 53 | python-shell-interpreter)))) 54 | 55 | (defun helm-pydoc--collect-imported-modules () 56 | (with-helm-current-buffer 57 | (save-excursion 58 | (goto-char (point-min)) 59 | (let ((modules nil)) 60 | (while (re-search-forward "^\\s-*\\(?:import\\|from\\)\\s-+\\([^ \t\r\n]+\\)" nil t) 61 | (push (match-string-no-properties 1) modules)) 62 | (reverse modules))))) 63 | 64 | (defun helm-pydoc--init () 65 | (with-current-buffer (helm-candidate-buffer 'global) 66 | (unless (zerop (call-process (helm-pydoc--python) nil t nil 67 | helm-pydoc--collect-command)) 68 | (error "Failed helm-pydoc--init")))) 69 | 70 | (defsubst helm-pydoc--pydoc-buffer (module) 71 | (get-buffer-create (format "*Pydoc %s*" module))) 72 | 73 | (defun helm-pydoc--do-pydoc (module) 74 | (with-current-buffer (helm-pydoc--pydoc-buffer module) 75 | (view-mode -1) 76 | (erase-buffer) 77 | (unless (zerop (call-process (helm-pydoc--python) nil t nil "-m" "pydoc" module)) 78 | (error "Failed: 'pydoc'")) 79 | (goto-char (point-min)) 80 | (view-mode +1) 81 | (pop-to-buffer (current-buffer)))) 82 | 83 | (defun helm-pydoc--module-file (module) 84 | (with-temp-buffer 85 | (let ((import-expression (format "import %s;print(%s.__file__)" module module))) 86 | (unless (zerop (call-process (helm-pydoc--python) nil t nil 87 | "-c" import-expression)) 88 | (error "Not found module '%s' source code" module)) 89 | (goto-char (point-min)) 90 | (let ((modname (buffer-substring (point) (line-end-position)))) 91 | (if (string-match "\\`\\(\.+\\.py\\)c\\'" modname) 92 | (match-string-no-properties 1 modname) 93 | modname))))) 94 | 95 | (defun helm-pydoc--view-source (candidate) 96 | (let ((modfile (helm-pydoc--module-file candidate))) 97 | (find-file-read-only-other-window modfile))) 98 | 99 | (defun helm-pydoc--check-imported (module) 100 | (save-excursion 101 | (let ((regexp (format "^\\s-*\\(?:from\\|import\\)\\s-+%s\\>" module))) 102 | (re-search-backward regexp nil t)))) 103 | 104 | (defun helm-pydoc--collect-import-modules () 105 | (cl-loop for module in (helm-marked-candidates) 106 | when (not (helm-pydoc--check-imported module)) 107 | collect module into modules 108 | finally return (sort modules 'string<))) 109 | 110 | (defun helm-pydoc--construct-import-statement (modules) 111 | (cond ((null (cdr modules)) 112 | (format "import %s\n" (car modules))) 113 | (t 114 | (mapconcat (lambda (m) (concat "import " m)) modules "\n")))) 115 | 116 | (defun helm-pydoc--insert-import-statement (inserted) 117 | (save-excursion 118 | (goto-char (line-end-position)) 119 | (if (re-search-backward "^\\s-*\\(?:from\\|import\\)\\s-+" nil t) 120 | (forward-line 1) 121 | (helm-pydoc--skip-comments)) 122 | (insert inserted))) 123 | 124 | (defun helm-pydoc--skip-comments () 125 | (goto-char (point-min)) 126 | (cl-loop while (string-match-p "\\`#" (buffer-substring-no-properties 127 | (line-beginning-position) 128 | (line-end-position))) 129 | do 130 | (forward-line 1))) 131 | 132 | (defun helm-pydoc--import-module (_candidate) 133 | (let* ((modules (helm-pydoc--collect-import-modules)) 134 | (statements (helm-pydoc--construct-import-statement modules))) 135 | (helm-pydoc--insert-import-statement statements))) 136 | 137 | (defun helm-pydoc--construct-from-import (module imports &optional name) 138 | (format "from %s import %s%s\n" 139 | module imports 140 | (if name 141 | (format " as name") 142 | ""))) 143 | 144 | (defun helm-pydoc--from-import-module (candidate) 145 | (let* ((imports (read-string (format "Identifiers in %s: " candidate))) 146 | (statement (helm-pydoc--construct-from-import candidate imports))) 147 | (helm-pydoc--insert-import-statement statement))) 148 | 149 | (defun helm-pydoc--from-import-as-module (candidate) 150 | (let* ((imports (read-string (format "Identifiers in %s: " candidate))) 151 | (name (read-string (format "As name [%s]: " candidate))) 152 | (statement (helm-pydoc--construct-from-import 153 | candidate imports name))) 154 | (helm-pydoc--insert-import-statement statement))) 155 | 156 | (defvar helm-pydoc--actions 157 | '(("Pydoc Module" . helm-pydoc--do-pydoc) 158 | ("View Source Code" . helm-pydoc--view-source) 159 | ("Import Module(import module)" . helm-pydoc--import-module) 160 | ("Import Module(from module import identifiers)" 161 | . helm-pydoc--from-import-module) 162 | ("Import Module(from module import identifiers as name)" 163 | . helm-pydoc--from-import-as-module))) 164 | 165 | (defvar helm-pydoc--imported-source 166 | (helm-build-sync-source "Imported Modules" 167 | :candidates 'helm-pydoc--collect-imported-modules 168 | :action helm-pydoc--actions 169 | :candidate-number-limit 9999)) 170 | 171 | (defvar helm-pydoc--installed-source 172 | (helm-build-in-buffer-source "Installed Modules" 173 | :init 'helm-pydoc--init 174 | :action helm-pydoc--actions 175 | :candidate-number-limit 9999)) 176 | 177 | (defvar helm-pydoc--history nil) 178 | 179 | ;;;###autoload 180 | (defun helm-pydoc () 181 | (interactive) 182 | (helm :sources '(helm-pydoc--imported-source helm-pydoc--installed-source) 183 | :buffer "*helm pydoc*" :history 'helm-pydoc--history)) 184 | 185 | (provide 'helm-pydoc) 186 | 187 | ;;; helm-pydoc.el ends here 188 | --------------------------------------------------------------------------------