Codebase list pip-requirements-el / a8a6019
New upstream version 0.5 Lev Lamberov 6 years ago
5 changed file(s) with 236 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 (source gnu)
1 (source melpa)
2
3 (package-file "pip-requirements.el")
4
5 (depends-on "dash")
0 # pip-requirements.el
1
2 [![MELPA](http://melpa.org/packages/pip-requirements-badge.svg)](http://melpa.org/#/pip-requirements)
3 [![MELPA Stable](http://stable.melpa.org/packages/pip-requirements-badge.svg)](http://stable.melpa.org/#/pip-requirements)
4
5 This is a major mode for editing pip requirements files, with the following features:
6
7 * Syntax highlighting
8 * Togglable comments
9 * Auto completion of package names from PyPI
10
11 ![pip-requirements](pip_requirements_screenshot.png)
12
13 ## Auto Completion
14
15 This major mode provides completion of package names from PyPI. It supports
16 Emacs' built-in `completion-at-point` command and thus also [Company][] via its
17 generic CAPF backend.
18
19 To use [Auto Complete][] instead, add the following to your `init.el`:
20
21 ```cl
22 (add-hook 'pip-requirements-mode-hook #'pip-requirements-auto-complete-setup)
23 ```
24
25 [Company]: https://github.com/company-mode/company-mode
26 [Auto Complete]: https://github.com/auto-complete/auto-complete
27
28 ## Changelog
29
30 ### 0.5
31
32 Added support for completion-at-point-functions. Autocomplete is now
33 optional, and pip-requirements also works with company (via
34 `company-capf`).
35
36 `.` and `_` are now supported in package names, and `.postN` is now
37 supported in version numbers.
38
39 `pip-requirements-mode` now inherits from `prog-mode`.
40
41 `requirements.in` files are now recognised as pip requirements files.
42
43 ### 0.4
44
45 Auto-completion of package names! See screenshot above. Requires
46 auto-complete, and your Emacs must be compiled with libxml support.
47
48 Added support for toggling comments with `M-;`.
49
50 ### 0.3
51
52 Improved syntax highlighting in different version strings. Improved
53 detection of pip requirements files (it's now anything that matches
54 `*.pip` or `requirements*.txt`).
55
56 ### 0.2
57
58 First public release, just syntax highlighting.
59
60 ## Credits
61
62 This package is very much inspired by
63 https://github.com/wuub/requirementstxt for Sublime.
0 # I'm a comment!
1 Django==1.2.3
2 foo[bar]==1.2
3 baz>1,<2
4 python-dateutil>=1.5,<=2.1,!=2.0
5 backports.ssl-match-hostname==3.4.0.2
0 ;;; pip-requirements.el --- A major mode for editing pip requirements files.
1
2 ;; Copyright (C) 2014 Wilfred Hughes <me@wilfred.me.uk>
3 ;;
4 ;; Author: Wilfred Hughes <me@wilfred.me.uk>
5 ;; Created: 11 September 2014
6 ;; Version: 0.5
7 ;; Package-Requires: ((dash "2.8.0"))
8
9 ;;; License:
10
11 ;; This file is not part of GNU Emacs.
12 ;; However, it is distributed under the same license.
13
14 ;; GNU Emacs is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; any later version.
18
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
28
29 ;;; Commentary:
30
31 ;; This is a major mode for editing pip requirements files, with the following features:
32
33 ;; * Syntax highlighting
34 ;; * Togglable comments
35 ;; * Auto completion of package names from PyPI
36
37 ;; TODO: Steal shamelessly all the fantasic ideas in
38 ;; https://github.com/wuub/requirementstxt
39
40 ;;; Code:
41
42 (require 'dash)
43 (require 'cl-lib)
44
45 (defgroup pip-requirements nil
46 "Requirements files for pip"
47 :prefix "pip-requirements-"
48 :group 'languages
49 :link '(url-link :tag "Github" "https://github.com/Wilfred/pip-requirements.el"))
50
51 (defcustom pip-requirements-mode-hook nil
52 "Hook to run after `pip-requirements-mode'."
53 :group 'pip-requirements
54 :type 'hook
55 :risky t)
56
57 ;;;###autoload
58 (add-to-list 'auto-mode-alist
59 `(,(rx ".pip" string-end) . pip-requirements-mode))
60 ;;;###autoload
61 (add-to-list 'auto-mode-alist
62 `(,(rx "requirements" (zero-or-more anything) ".txt" string-end) . pip-requirements-mode))
63
64 ;;;###autoload
65 (add-to-list 'auto-mode-alist
66 `(,(rx "requirements.in") . pip-requirements-mode))
67
68 (defconst pip-requirements-name-regex
69 (rx
70 line-start
71 (group (1+ (or alphanumeric "-" "_" ".")))))
72
73 (defconst pip-requirements-version-regex
74 (rx
75 (group (or "==" ">" ">=" "<" "<=" "!="))
76 (group (1+ (or digit "b" "." "post")))))
77
78 (defconst pip-requirements-operators
79 (list
80 (list pip-requirements-name-regex 1 'font-lock-variable-name-face)
81 (list pip-requirements-version-regex 1 'font-lock-builtin-face)
82 (list pip-requirements-version-regex 2 'font-lock-constant-face)))
83
84 (defconst pip-requirements-syntax-table
85 (let ((table (make-syntax-table)))
86 (modify-syntax-entry ?# "<" table)
87 (modify-syntax-entry ?\n ">" table)
88 table))
89
90 (defvar pip-http-buffer nil)
91 (defvar pip-packages nil
92 "List of PyPI packages for completion.")
93
94 (defun pip-requirements-callback (&rest _)
95 (with-current-buffer pip-http-buffer
96 ;; Move over the HTTP header.
97 (goto-char (point-min))
98 (re-search-forward "^$" nil 'move)
99
100 (setq pip-packages
101 (->> (libxml-parse-html-region (point) (point-max))
102 ;; Get the body tag.
103 -last-item
104 ;; Immediate children of the body.
105 cdr cdr cdr
106 ;; Anchor tags.
107 (--filter (eq (car it) 'a))
108 ;; Inner text of anchor tags.
109 (-map #'cl-third))))
110 (kill-buffer pip-http-buffer))
111
112 (defun pip-requirements-fetch-packages ()
113 "Get a list of all packages available on PyPI and store them in `pip-packages'.
114 Assumes Emacs is compiled with libxml."
115 (setq pip-http-buffer
116 (url-retrieve "https://pypi.python.org/simple/"
117 #'pip-requirements-callback nil t)))
118
119 (defun pip-requirements-complete-at-point ()
120 "Complete at point in Pip Requirements Mode."
121 (let* ((bounds (bounds-of-thing-at-point 'symbol))
122 (start (or (car bounds) (point)))
123 (end (or (cdr bounds) (point))))
124 (list start end pip-packages)))
125
126 ;; Declare variables from AC, to avoid a hard dependency on Auto Complete.
127 (defvar ac-modes)
128 (defvar ac-sources)
129
130 ;;;###autoload
131 (defun pip-requirements-auto-complete-setup ()
132 "Setup Auto-Complete for Pip Requirements.
133
134 See URL `https://github.com/auto-complete/auto-complete' for
135 information about Auto Complete."
136 (add-to-list 'ac-modes 'pip-requirements-mode)
137 (add-to-list 'ac-sources '((candidates . pip-packages)))
138 (when (and (fboundp 'auto-complete-mode)
139 (not (bound-and-true-p auto-complete-mode)))
140 ;; Enable Auto Complete
141 (auto-complete-mode)))
142
143 (custom-add-frequent-value 'pip-requirements-mode-hook
144 'pip-requirements-auto-complete-setup)
145
146 ;;;###autoload
147 (define-derived-mode pip-requirements-mode prog-mode "pip-require"
148 "Major mode for editing pip requirements files."
149 :syntax-table pip-requirements-syntax-table
150 (set (make-local-variable 'font-lock-defaults) '(pip-requirements-operators))
151 (set (make-local-variable 'comment-start) "#")
152 (add-hook 'completion-at-point-functions
153 #'pip-requirements-complete-at-point nil 'local)
154 (unless pip-packages
155 ;; Fetch the list of packages for completion
156 (pip-requirements-fetch-packages)))
157
158 (provide 'pip-requirements)
159 ;;; pip-requirements.el ends here