Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 430 lines (368 sloc) 15.46 kb
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
1 ;;; helm-regexp.el --- In buffer regexp searching and replacement for helm.
2
3 ;; Copyright (C) 2012 Thierry Volpiatto <thierry.volpiatto@gmail.com>
4
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, either version 3 of the License, or
8 ;; (at your option) any later version.
9
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
14
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 ;;; Code:
19
20 (require 'cl)
21 (require 'helm)
ba17f09 @thierryvolpiatto Move all defcustoms and faces in their respectives groups and files.
thierryvolpiatto authored
22 (require 'helm-utils)
23
24
25 (defgroup helm-regexp nil
26 "Regexp related Applications and libraries for Helm."
27 :group 'helm)
28
29 (defcustom helm-c-browse-code-regexp-lisp
30 "^ *\(def\\(un\\|subst\\|macro\\|face\\|alias\\|advice\\|struct\\|\
31 type\\|theme\\|var\\|group\\|custom\\|const\\|method\\|class\\)"
32 "Regexp used to parse lisp buffer when browsing code."
33 :type 'string
34 :group 'helm-regexp)
35
36 (defcustom helm-c-browse-code-regexp-python
37 "\\<def\\>\\|\\<class\\>"
38 "Regexp used to parse python buffer when browsing code."
39 :type 'string
40 :group 'helm-regexp)
41
42 (defcustom helm-c-browse-code-regexp-alist
43 `((lisp-interaction-mode . ,helm-c-browse-code-regexp-lisp)
44 (emacs-lisp-mode . ,helm-c-browse-code-regexp-lisp)
45 (lisp-mode . ,helm-c-browse-code-regexp-lisp)
46 (python-mode . ,helm-c-browse-code-regexp-python))
47 "Alist to store regexps for browsing code corresponding \
48 to a specific `major-mode'."
d079fc3 @thierryvolpiatto Issue #95 Fix defcustoms in various places.
thierryvolpiatto authored
49 :type '(alist :key-type symbol :value-type regexp)
ba17f09 @thierryvolpiatto Move all defcustoms and faces in their respectives groups and files.
thierryvolpiatto authored
50 :group 'helm-regexp)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
51
52 (defface helm-moccur-buffer
53 '((t (:foreground "DarkTurquoise" :underline t)))
54 "Face used to highlight moccur buffer names."
55 :group 'helm-regexp)
ba17f09 @thierryvolpiatto Move all defcustoms and faces in their respectives groups and files.
thierryvolpiatto authored
56
57
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
58 (defvar helm-occur-map
59 (let ((map (make-sparse-keymap)))
60 (set-keymap-parent map helm-map)
61 (define-key map (kbd "C-M-%") 'helm-occur-run-query-replace-regexp)
62 map)
63 "Keymap for `helm-occur'.")
64
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
65 (defvar helm-c-moccur-map
66 (let ((map (make-sparse-keymap)))
67 (set-keymap-parent map helm-map)
68 (define-key map (kbd "M-<down>") 'helm-c-goto-next-file)
69 (define-key map (kbd "M-<up>") 'helm-c-goto-precedent-file)
70 (define-key map (kbd "C-w") 'helm-yank-text-at-point)
b3194af @thierryvolpiatto Add help for moccur.
thierryvolpiatto authored
71 (define-key map (kbd "C-c ?") 'helm-moccur-help)
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
72 (delq nil map))
73 "Keymap used in Moccur source.")
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
74
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
75 (defvar helm-build-regexp-history nil)
76 (defun helm-c-query-replace-regexp (candidate)
77 "Query replace regexp from `helm-regexp'.
78 With a prefix arg replace only matches surrounded by word boundaries,
79 i.e Don't replace inside a word, regexp is surrounded with \\bregexp\\b."
80 (let ((regexp (funcall (helm-attr 'regexp))))
81 (apply 'query-replace-regexp
82 (helm-c-query-replace-args regexp))))
83
84 (defun helm-c-kill-regexp-as-sexp (candidate)
85 "Kill regexp in a format usable in lisp code."
86 (helm-c-regexp-kill-new
87 (prin1-to-string (funcall (helm-attr 'regexp)))))
88
89 (defun helm-c-kill-regexp (candidate)
90 "Kill regexp as it is in `helm-pattern'."
91 (helm-c-regexp-kill-new (funcall (helm-attr 'regexp))))
92
93 (defun helm-c-query-replace-args (regexp)
94 "create arguments of `query-replace-regexp' action in `helm-regexp'."
95 (let ((region-only (helm-region-active-p)))
96 (list
97 regexp
98 (query-replace-read-to regexp
99 (format "Query replace %sregexp %s"
100 (if helm-current-prefix-arg "word " "")
101 (if region-only "in region " ""))
102 t)
103 helm-current-prefix-arg
104 (when region-only (region-beginning))
105 (when region-only (region-end)))))
106
107 (defvar helm-c-source-regexp
108 '((name . "Regexp Builder")
109 (init . (lambda ()
110 (helm-candidate-buffer helm-current-buffer)))
111 (candidates-in-buffer)
112 (get-line . helm-c-regexp-get-line)
113 (persistent-action . helm-c-regexp-persistent-action)
114 (persistent-help . "Show this line")
115 (multiline)
116 (delayed)
117 (requires-pattern . 2)
118 (mode-line . "Press TAB to select action.")
119 (regexp . (lambda () helm-input))
120 (action . (("Kill Regexp as sexp" . helm-c-kill-regexp-as-sexp)
121 ("Query Replace Regexp (C-u Not inside word.)"
122 . helm-c-query-replace-regexp)
123 ("Kill Regexp" . helm-c-kill-regexp)))))
124
125 (defun helm-c-regexp-get-line (s e)
126 (propertize
127 (apply 'concat
128 ;; Line contents
129 (format "%5d: %s" (line-number-at-pos (1- s)) (buffer-substring s e))
130 ;; subexps
131 (loop for i from 0 to (1- (/ (length (match-data)) 2))
132 collect (format "\n %s'%s'"
133 (if (zerop i) "Group 0: " (format "Group %d: " i))
134 (match-string i))))
135 ;; match beginning
136 ;; KLUDGE: point of helm-candidate-buffer is +1 than that of helm-current-buffer.
137 ;; It is implementation problem of candidates-in-buffer.
138 'helm-realvalue
139 (1- s)))
140
141 (defun helm-c-regexp-persistent-action (pt)
142 (helm-goto-char pt)
143 (helm-persistent-highlight-point))
144
145 (defun helm-c-regexp-kill-new (input)
146 (kill-new input)
147 (message "Killed: %s" input))
148
149 (defun helm-quote-whitespace (candidate)
150 "Quote whitespace, if some, in string CANDIDATE."
151 (replace-regexp-in-string " " "\\\\ " candidate))
152
153 ;;; Occur
154 ;;
155 ;;
156 (defun helm-c-occur-init ()
157 "Create the initial helm occur buffer.
158 If region is active use region as buffer contents
159 instead of whole buffer."
160 (with-current-buffer (helm-candidate-buffer 'global)
161 (erase-buffer)
162 (let ((buf-contents
163 (with-helm-current-buffer
164 (if (helm-region-active-p)
165 (buffer-substring (region-beginning) (region-end))
166 (buffer-substring (point-min) (point-max))))))
167 (insert buf-contents))))
168
169 (defun helm-c-occur-get-line (s e)
170 (format "%7d:%s" (line-number-at-pos (1- s)) (buffer-substring s e)))
171
172 (defun helm-c-occur-query-replace-regexp (candidate)
173 "Query replace regexp starting from CANDIDATE.
174 If region is active ignore CANDIDATE and replace only in region.
175 With a prefix arg replace only matches surrounded by word boundaries,
176 i.e Don't replace inside a word, regexp is surrounded with \\bregexp\\b."
177 (let ((regexp helm-input))
178 (unless (helm-region-active-p)
179 (helm-c-action-line-goto candidate))
180 (apply 'query-replace-regexp
181 (helm-c-query-replace-args regexp))))
182
183 (defun helm-occur-run-query-replace-regexp ()
184 "Run `query-replace-regexp' in helm occur from keymap."
185 (interactive)
186 (helm-c-quit-and-execute-action
187 'helm-c-occur-query-replace-regexp))
188
189 (defvar helm-c-source-occur
190 `((name . "Occur")
191 (init . helm-c-occur-init)
192 (candidates-in-buffer)
bec9d22 @thierryvolpiatto Revert changes for migemo, add migemo attr to multi-occur.
thierryvolpiatto authored
193 (migemo)
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
194 (get-line . helm-c-occur-get-line)
0ea6be6 @thierryvolpiatto * helm-regexp.el (helm-c-display-to-real-numbered-line): Renamed from…
thierryvolpiatto authored
195 (display-to-real . helm-c-display-to-real-numbered-line)
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
196 (action . (("Go to Line" . helm-c-action-line-goto)
197 ("Query replace regexp (C-u Not inside word.)"
198 . helm-c-occur-query-replace-regexp)))
199 (recenter)
200 (mode-line . helm-occur-mode-line)
201 (keymap . ,helm-occur-map)
202 (requires-pattern . 1)
203 (delayed)))
204
f5d0706 @thierryvolpiatto * helm-config.el: Move browse-code to helm-regexp.el
thierryvolpiatto authored
205
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
206 ;;; Multi occur
207 ;;
208 ;;
209 (defun helm-m-occur-init (buffers)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
210 "Create the initial helm multi occur buffer."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
211 (helm-init-candidates-in-buffer
c23a0af @thierryvolpiatto * helm.el (helm-init-candidates-in-buffer): Allow a symbol for BUFFER…
thierryvolpiatto authored
212 'global
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
213 (loop for buf in buffers
214 for bufstr = (with-current-buffer buf (buffer-string))
215 do (add-text-properties
216 0 (length bufstr)
217 `(buffer-name ,(buffer-name (get-buffer buf)))
218 bufstr)
219 concat bufstr)))
220
221 (defun helm-m-occur-get-line (s e)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
222 "Format line for `helm-c-source-moccur'."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
223 (format "%s:%d:%s"
224 (get-text-property (point-at-bol) 'buffer-name)
225 (save-restriction
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
226 (narrow-to-region (previous-single-property-change
227 (point) 'buffer-name)
228 (next-single-property-change
229 (point) 'buffer-name))
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
230 (line-number-at-pos s))
231 (buffer-substring s e)))
232
233 (defun* helm-m-occur-action (candidate
234 &optional (method (quote buffer)))
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
235 "Jump to CANDIDATE with METHOD.
236 arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
237 (let* ((split (split-string candidate ":" t))
238 (buf (car split))
239 (lineno (string-to-number (nth 1 split))))
240 (case method
241 (buffer (switch-to-buffer buf))
242 (buffer-other-window (switch-to-buffer-other-window buf))
243 (buffer-other-frame (switch-to-buffer-other-frame buf)))
244 (helm-goto-line lineno)))
245
246 (defun helm-m-occur-goto-line (candidate)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
247 "From multi occur, switch to buffer and go to nth 1 CANDIDATE line."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
248 (helm-m-occur-action candidate))
249
250 (defvar helm-c-source-moccur
251 `((name . "Moccur")
252 (init . (lambda ()
253 (helm-m-occur-init buffers)))
254 (candidates-in-buffer)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
255 (filtered-candidate-transformer . helm-m-occur-transformer)
256 (nohighlight)
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
257 (get-line . helm-m-occur-get-line)
bec9d22 @thierryvolpiatto Revert changes for migemo, add migemo attr to multi-occur.
thierryvolpiatto authored
258 (migemo)
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
259 (action . (("Go to Line" . helm-m-occur-goto-line)))
260 (recenter)
261 (candidate-number-limit . 9999)
b3194af @thierryvolpiatto Add help for moccur.
thierryvolpiatto authored
262 (mode-line . helm-moccur-mode-line)
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
263 (keymap . ,helm-c-moccur-map)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
264 (requires-pattern . 3))
265 "Helm source for multi occur.")
266
267 (defun helm-m-occur-transformer (candidates source)
268 "Transformer function for `helm-c-source-moccur'."
269 (require 'helm-grep)
270 (loop for i in candidates
271 for split = (split-string i ":" t)
272 for buf = (car split)
273 for lineno = (nth 1 split)
274 for str = (nth 2 split)
275 collect (cons (concat (propertize buf 'face 'helm-moccur-buffer
276 'buffer-name buf)
277 ":"
278 (propertize lineno 'face 'helm-grep-lineno)
279 ":"
280 (helm-c-grep-highlight-match str))
281 i)))
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
282
283 (defun helm-multi-occur-1 (buffers)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
284 "Main function to call `helm-c-source-moccur' with BUFFERS list."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
285 (declare (special buffers))
286 (helm :sources 'helm-c-source-moccur
287 :buffer "*helm moccur*"))
288
289
f5d0706 @thierryvolpiatto * helm-config.el: Move browse-code to helm-regexp.el
thierryvolpiatto authored
290 ;;; Helm browse code.
291 (defun helm-c-browse-code-get-line (beg end)
292 "Select line if it match the regexp corresponding to current `major-mode'.
293 Line is parsed for BEG position to END position."
294 (let ((str-line (buffer-substring beg end))
295 (regexp (assoc-default major-mode
296 helm-c-browse-code-regexp-alist))
297 (num-line (if (string= helm-pattern "") beg (1- beg))))
298 (when (and regexp (string-match regexp str-line))
299 (format "%4d:%s" (line-number-at-pos num-line) str-line))))
300
301 (defvar helm-c-source-browse-code
302 '((name . "Browse code")
303 (init . (lambda ()
304 (helm-candidate-buffer helm-current-buffer)
305 (with-helm-current-buffer
306 (jit-lock-fontify-now))))
307 (candidate-number-limit . 9999)
308 (candidates-in-buffer)
309 (get-line . helm-c-browse-code-get-line)
310 (type . line)
311 (recenter)))
312
0ea6be6 @thierryvolpiatto * helm-regexp.el (helm-c-display-to-real-numbered-line): Renamed from…
thierryvolpiatto authored
313 (defun helm-c-display-to-real-numbered-line (candidate)
314 "This is used to display a line in occur style in helm sources.
315 e.g \" 12:some_text\".
316 It is used with type attribute 'line'."
317 (if (string-match "^ *\\([0-9]+\\):\\(.*\\)$" candidate)
318 (list (string-to-number (match-string 1 candidate))
319 (match-string 2 candidate))
320 (error "Line number not found")))
321
7974fc5 @thierryvolpiatto Create autoload system in helm-config.
thierryvolpiatto authored
322 ;;; Type attributes
323 ;;
324 ;;
325 (define-helm-type-attribute 'line
0ea6be6 @thierryvolpiatto * helm-regexp.el (helm-c-display-to-real-numbered-line): Renamed from…
thierryvolpiatto authored
326 '((display-to-real . helm-c-display-to-real-numbered-line)
7974fc5 @thierryvolpiatto Create autoload system in helm-config.
thierryvolpiatto authored
327 (action ("Go to Line" . helm-c-action-line-goto)))
328 "LINENO:CONTENT string, eg. \" 16:foo\".
329
330 Optional `target-file' attribute is a name of target file.
331
332 Optional `before-jump-hook' attribute is a function with no
333 arguments which is called before jumping to position.
334
335 Optional `after-jump-hook' attribute is a function with no
336 arguments which is called after jumping to position.
337
338 If `adjust' attribute is specified, searches the line whose
339 content is CONTENT near the LINENO.
340
341 If `recenter' attribute is specified, the line is displayed at
342 the center of window, otherwise at the top of window.")
343
344 (define-helm-type-attribute 'file-line
345 `((filtered-candidate-transformer helm-c-filtered-candidate-transformer-file-line)
346 (multiline)
347 (action ("Go to" . helm-c-action-file-line-goto)))
348 "FILENAME:LINENO:CONTENT string, eg. \"~/.emacs:16:;; comment\".
349
350 Optional `default-directory' attribute is a default-directory
351 FILENAME is interpreted.
352
353 Optional `before-jump-hook' attribute is a function with no
354 arguments which is called before jumping to position.
355
356 Optional `after-jump-hook' attribute is a function with no
357 arguments which is called after jumping to position.
358
359 If `adjust' attribute is specified, searches the line whose
360 content is CONTENT near the LINENO.
361
362 If `recenter' attribute is specified, the line is displayed at
363 the center of window, otherwise at the top of window.")
364
f97a20c @thierryvolpiatto * helm-config.el: Move *find-files and related to helm-files.el
thierryvolpiatto authored
365 ;;;###autoload
366 (defun helm-regexp ()
367 "Preconfigured helm to build regexps.
368 `query-replace-regexp' can be run from there against found regexp."
369 (interactive)
370 (save-restriction
371 (let ((helm-compile-source-functions
372 ;; rule out helm-match-plugin because the input is one regexp.
373 (delq 'helm-compile-source--match-plugin
374 (copy-sequence helm-compile-source-functions))))
375 (when (and (helm-region-active-p)
376 ;; Don't narrow to region if buffer is already narrowed.
377 (not (helm-current-buffer-narrowed-p)))
378 (narrow-to-region (region-beginning) (region-end)))
379 (helm :sources helm-c-source-regexp
380 :buffer "*helm regexp*"
381 :prompt "Regexp: "
382 :history 'helm-build-regexp-history))))
383
e21f4c8 @thierryvolpiatto * helm-config.el: Move lisp completion code to helm-elisp.el
thierryvolpiatto authored
384 ;;;###autoload
385 (defun helm-occur ()
386 "Preconfigured Helm for Occur source.
387 If region is active, search only in region,
388 otherwise search in whole buffer."
389 (interactive)
390 (let ((helm-compile-source-functions
391 ;; rule out helm-match-plugin because the input is one regexp.
392 (delq 'helm-compile-source--match-plugin
393 (copy-sequence helm-compile-source-functions))))
394 (helm :sources 'helm-c-source-occur
395 :buffer "*Helm Occur*"
396 :history 'helm-c-grep-history)))
397
f5d0706 @thierryvolpiatto * helm-config.el: Move browse-code to helm-regexp.el
thierryvolpiatto authored
398 ;;;###autoload
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
399 (defun helm-multi-occur ()
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
400 "Preconfigured helm for multi occur."
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
401 (interactive)
9f15d07 @thierryvolpiatto Add transformer function to multi occur.
thierryvolpiatto authored
402 (let ((helm-compile-source-functions
403 ;; rule out helm-match-plugin because the input is one regexp.
404 (delq 'helm-compile-source--match-plugin
405 (copy-sequence helm-compile-source-functions)))
406 (buffers (helm-comp-read
7288a9a @thierryvolpiatto Introduce multi occur.
thierryvolpiatto authored
407 "Buffers: " (helm-c-buffer-list)
408 :marked-candidates t)))
409 (helm-multi-occur-1 buffers)))
410
411 ;;;###autoload
f5d0706 @thierryvolpiatto * helm-config.el: Move browse-code to helm-regexp.el
thierryvolpiatto authored
412 (defun helm-browse-code ()
413 "Preconfigured helm to browse code."
414 (interactive)
415 (helm :sources 'helm-c-source-browse-code
416 :buffer "*helm browse code*"
417 :default (thing-at-point 'symbol)))
418
419
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
420 (provide 'helm-regexp)
421
37b4201 @thierryvolpiatto Fix dependencies and autoloads. Reorder.
thierryvolpiatto authored
422 ;; Local Variables:
a7ee65b @thierryvolpiatto Disable compile warnings and add new keyword to helm.
thierryvolpiatto authored
423 ;; byte-compile-warnings: (not cl-functions obsolete)
37b4201 @thierryvolpiatto Fix dependencies and autoloads. Reorder.
thierryvolpiatto authored
424 ;; coding: utf-8
425 ;; indent-tabs-mode: nil
426 ;; byte-compile-dynamic: t
427 ;; End:
428
3d768cc @thierryvolpiatto * helm-config.el: Move regexp and occur code to helm-regexp.el.
thierryvolpiatto authored
429 ;;; helm-regexp.el ends here
Something went wrong with that request. Please try again.