1
- ; ;; isearch-project.el --- Incremental search through the whole project. -*- lexical-binding : t ; -*-
1
+ ; ;; isearch-project.el --- Incremental search through the whole project -*- lexical-binding : t ; -*-
2
2
3
3
; ; Copyright (C) 2019 Shen, Jen-Chieh
4
4
; ; Created date 2019-03-18 15:16:04
7
7
; ; Description: Incremental search through the whole project.
8
8
; ; Keyword: convenience, search
9
9
; ; Version: 0.0.7
10
- ; ; Package-Requires: ((emacs "25 ") (cl-lib "0.6"))
10
+ ; ; Package-Requires: ((emacs "26.1 ") (cl-lib "0.6") (f "0.20.0 "))
11
11
; ; URL: https://github.com/jcs090218/isearch-project
12
12
13
13
; ; This file is NOT part of GNU Emacs.
33
33
; ;; Code:
34
34
35
35
(require 'cl-lib )
36
+ (require 'f )
36
37
(require 'grep )
37
38
(require 'isearch )
38
39
52
53
:group 'isearch-project )
53
54
54
55
55
- (defvar isearch-project-search-path " "
56
+ (defvar isearch-project-- search-path " "
56
57
" Record the current search path, so when next time it searhs would not need to research from the start." )
57
58
58
- (defvar isearch-project-project-dir " "
59
+ (defvar isearch-project-- project-dir " "
59
60
" Current isearch project directory." )
60
61
61
- (defvar isearch-project-files '()
62
+ (defvar isearch-project-- files '()
62
63
" List of file path in the project." )
63
64
64
- (defvar isearch-project-files-starting-index -1
65
- " Starting search path index, use with `isearch-project-files' list." )
65
+ (defvar isearch-project-- files-starting-index -1
66
+ " Starting search path index, use with `isearch-project-- files' list." )
66
67
67
- (defvar isearch-project-files-current-index -1
68
- " Current search path index, use with `isearch-project-files' list." )
68
+ (defvar isearch-project-- files-current-index -1
69
+ " Current search path index, use with `isearch-project-- files' list." )
69
70
70
- (defvar isearch-project-run-advice t
71
+ (defvar isearch-project-- run-advice t
71
72
" Flag to check if run advice." )
72
73
73
- (defvar isearch-project-thing-at-point " "
74
+ (defvar isearch-project-- thing-at-point " "
74
75
" Record down the symbol while executing `isearch-project-forward-symbol-at-point' command." )
75
76
76
77
77
- (defun isearch-project-is-contain-list-string (in-list in-str )
78
+ (defun isearch-project-- is-contain-list-string (in-list in-str )
78
79
" Check if a string contain in any string in the string list.
79
80
IN-LIST : list of string use to check if IN-STR in contain one of
80
81
the string.
81
82
IN-STR : string using to check if is contain one of the IN-LIST."
82
83
(cl-some #' (lambda (lb-sub-str ) (string-match-p (regexp-quote lb-sub-str) in-str)) in-list))
83
84
84
- (defun isearch-project-remove-nth-element (n lst )
85
+ (defun isearch-project-- remove-nth-element (n lst )
85
86
" Remove nth element from the list.
86
87
N : nth element you want to remove from the list.
87
88
LST : List you want to modified."
@@ -91,12 +92,38 @@ LST : List you want to modified."
91
92
(setcdr last (cddr last ))
92
93
lst)))
93
94
94
- (defun isearch-project-filter-directory-files-recursively (lst )
95
+ (defun isearch-project--f-directories-ignore-directories (path &optional rec )
96
+ " Find all directories in PATH by ignored common directories with FN and REC."
97
+ (let ((dirs (f-directories path))
98
+ (valid-dirs '())
99
+ (final-dirs '())
100
+ (ignore-lst (append grep-find-ignored-directories
101
+ isearch-project-ignore-paths
102
+ (if (boundp 'projectile-globally-ignored-directories )
103
+ projectile-globally-ignored-directories
104
+ '()))))
105
+ (dolist (dir dirs)
106
+ (unless (isearch-project--is-contain-list-string ignore-lst dir)
107
+ (push dir valid-dirs)))
108
+ (when rec
109
+ (dolist (dir valid-dirs)
110
+ (push (isearch-project--f-directories-ignore-directories dir rec) final-dirs)))
111
+ (setq valid-dirs (reverse valid-dirs))
112
+ (setq final-dirs (reverse final-dirs))
113
+ (jcs-flatten-list (append valid-dirs final-dirs))))
114
+
115
+ (defun isearch-project--f-files-ignore-directories (path &optional fn rec )
116
+ " Find all files in PATH by ignored common directories with FN and REC."
117
+ (let ((dirs (append (list path) (isearch-project--f-directories-ignore-directories path rec)))
118
+ (files '()))
119
+ (dolist (dir dirs)
120
+ (push (f-files dir fn) files ))
121
+ (jcs-flatten-list (reverse files ))))
122
+
123
+ (defun isearch-project--filter-directory-files-recursively (lst )
95
124
" Filter directory files.
96
125
LST : Directory files."
97
- (let ((index 0 )
98
- (path " " )
99
- (ignored-paths '()))
126
+ (let ((index 0 ) (path " " ) (ignored-paths '()))
100
127
(setq ignored-paths (mapcar #'copy-sequence grep-find-ignored-directories))
101
128
; ; Add / at the end of each path.
102
129
(while (< index (length ignored-paths))
@@ -113,24 +140,22 @@ LST : Directory files."
113
140
(setq path (nth index lst))
114
141
115
142
; ; Filter it.
116
- (if (isearch-project-is-contain-list-string ignored-paths path)
117
- (setq lst (isearch-project-remove-nth-element index lst))
143
+ (if (isearch-project-- is-contain-list-string ignored-paths path)
144
+ (setq lst (isearch-project-- remove-nth-element index lst))
118
145
(setq index (+ index 1 )))))
119
146
lst)
120
147
121
148
(defun isearch-project-prepare ()
122
149
" Incremental search preparation."
123
150
(let ((prepare-success nil ))
124
- (setq isearch-project-project-dir (cdr (project-current )))
125
- (when isearch-project-project-dir
151
+ (setq isearch-project-- project-dir (cdr (project-current )))
152
+ (when isearch-project-- project-dir
126
153
; ; Get the current buffer name.
127
- (setq isearch-project-search-path (buffer-file-name ))
128
- ; ; Get all the file from the project, and filter it.
129
- (setq isearch-project-files (directory-files-recursively isearch-project-project-dir " " ))
130
- (setq isearch-project-files (isearch-project-filter-directory-files-recursively isearch-project-files))
154
+ (setq isearch-project--search-path (buffer-file-name ))
155
+ ; ; Get all the file from the project, and filter it with ignore path list.
156
+ (setq isearch-project--files (isearch-project--f-files-ignore-directories isearch-project--project-dir nil t ))
131
157
; ; Reset to -1.
132
- (setq isearch-project-files-current-index -1 )
133
-
158
+ (setq isearch-project--files-current-index -1 )
134
159
(setq prepare-success t ))
135
160
prepare-success))
136
161
@@ -139,9 +164,9 @@ LST : Directory files."
139
164
(defun isearch-project-forward-symbol-at-point ()
140
165
" Incremental search forward at current point in the project."
141
166
(interactive )
142
- (setq isearch-project-thing-at-point (thing-at-point 'symbol ))
167
+ (setq isearch-project-- thing-at-point (thing-at-point 'symbol ))
143
168
(if (or (use-region-p )
144
- (char-or-string-p isearch-project-thing-at-point))
169
+ (char-or-string-p isearch-project-- thing-at-point))
145
170
(isearch-project-forward)
146
171
(error " Isearch project : no region or symbol at point " )))
147
172
@@ -187,60 +212,54 @@ If found, leave it. If not found, try find the next file.
187
212
FN : file to search.
188
213
DT : search direction."
189
214
(find-file fn)
190
- (cond ((eq dt 'forward )
191
- (goto-char (point-min )))
192
- ((eq dt 'backward )
193
- (goto-char (point-max ))))
215
+ (cl-case dt
216
+ ('forward (goto-char (point-min )))
217
+ ('backward (goto-char (point-max ))))
194
218
195
219
(isearch-search-string isearch-string nil t )
196
220
197
- (let ((isearch-project-run-advice nil ))
198
- (cond ((eq dt 'forward )
199
- (isearch-repeat-forward ))
200
- ((eq dt 'backward )
201
- (isearch-repeat-backward )))))
221
+ (let ((isearch-project--run-advice nil ))
222
+ (cl-case dt
223
+ ('forward (isearch-repeat-forward ))
224
+ ('backward (isearch-repeat-backward )))))
202
225
203
226
204
227
(defun isearch-project-advice-isearch-repeat-after (dt &optional cnt )
205
228
" Advice when do either `isearch-repeat-backward' or `isearch-repeat-forward' \
206
229
command.
207
230
DT : search direction.
208
231
CNT : search count."
209
- (when (and (not isearch-success)
210
- isearch-project-run-advice)
211
- (let ((next-file-index isearch-project-files-current-index)
212
- (next-fn " " ))
232
+ (when (and (not isearch-success) isearch-project--run-advice)
233
+ (let ((next-file-index isearch-project--files-current-index) (next-fn " " ))
213
234
; ; Get the next file index.
214
- (when (= isearch-project-files-current-index -1 )
215
- (setq isearch-project-files-current-index
216
- (cl-position isearch-project-search-path
217
- isearch-project-files
235
+ (when (= isearch-project-- files-current-index -1 )
236
+ (setq isearch-project-- files-current-index
237
+ (cl-position isearch-project-- search-path
238
+ isearch-project-- files
218
239
:test 'string= ))
219
- (setq next-file-index isearch-project-files-current-index))
240
+ (setq next-file-index isearch-project-- files-current-index))
220
241
221
242
; ; Record down the starting file index.
222
- (setq isearch-project-files-starting-index isearch-project-files-current-index)
243
+ (setq isearch-project-- files-starting-index isearch-project- -files-current-index)
223
244
224
- (let ((buf-content " " )
225
- (break-it nil )
226
- (search-cnt (if cnt cnt 1 )))
245
+ (let ((buf-content " " ) (break-it nil ) (search-cnt (if cnt cnt 1 )))
227
246
(while (not break-it)
228
247
; ; Get the next file index.
229
- (cond ((eq dt 'backward )
230
- (setq next-file-index (- next-file-index 1 )))
231
- ((eq dt 'forward )
232
- (setq next-file-index (+ next-file-index 1 ))))
248
+ (cl-case dt
249
+ ('backward (setq next-file-index (- next-file-index 1 )))
250
+ ('forward (setq next-file-index (+ next-file-index 1 ))))
233
251
234
252
; ; Cycle it.
235
- (cond ((eq dt 'backward )
236
- (when (< next-file-index 0 )
237
- (setq next-file-index (- (length isearch-project-files) 1 ))))
238
- ((eq dt 'forward )
239
- (when (>= next-file-index (length isearch-project-files))
240
- (setq next-file-index 0 ))))
253
+ (cl-case dt
254
+ ('backward
255
+ (when (< next-file-index 0 )
256
+ (setq next-file-index (- (length isearch-project--files) 1 ))))
257
+ ('forward
258
+ (when (>= next-file-index (length isearch-project--files))
259
+ (setq next-file-index 0 ))))
241
260
242
261
; ; Target the next file.
243
- (setq next-fn (nth next-file-index isearch-project-files))
262
+ (setq next-fn (nth next-file-index isearch-project-- files))
244
263
245
264
; ; Update buffer content.
246
265
(setq buf-content (isearch-project-get-string-from-file next-fn))
@@ -249,37 +268,35 @@ CNT : search count."
249
268
; ; Found match.
250
269
(isearch-project-contain-string isearch-string buf-content)
251
270
; ; Is the same as the starting file, this prevents infinite loop.
252
- (= isearch-project-files-starting-index next-file-index))
271
+ (= isearch-project-- files-starting-index next-file-index))
253
272
(setq search-cnt (- search-cnt 1 ))
254
- (when (<= search-cnt 0 )
255
- (setq break-it t )))))
273
+ (when (<= search-cnt 0 ) (setq break-it t )))))
256
274
257
275
; ; Open the file.
258
276
(isearch-project-find-file-search next-fn dt)
259
277
260
278
; ; Update current file index.
261
- (setq isearch-project-files-current-index next-file-index))))
279
+ (setq isearch-project-- files-current-index next-file-index))))
262
280
263
281
264
- (defun isearch-project-isearch-yank-string (search-str )
265
- " Isearch project allow arrow because we need to search through next file.
282
+ (defun isearch-project-- isearch-yank-string (search-str )
283
+ " Isearch project allow error because we need to search through next file.
266
284
SEARCH-STR : Search string."
267
- (ignore-errors
268
- (isearch-yank-string search-str)))
285
+ (ignore-errors (isearch-yank-string search-str)))
269
286
270
287
(defun isearch-project-isearch-mode-hook ()
271
288
" Paste the current symbol when `isearch' enabled."
272
289
(cond ((and (use-region-p )
273
290
(memq this-command '(isearch-project-forward isearch-project-forward-symbol-at-point)))
274
291
(let ((search-str (buffer-substring-no-properties (region-beginning ) (region-end ))))
275
292
(deactivate-mark )
276
- (isearch-project-isearch-yank-string search-str)))
293
+ (isearch-project-- isearch-yank-string search-str)))
277
294
((memq this-command '(isearch-project-forward-symbol-at-point))
278
- (when (char-or-string-p isearch-project-thing-at-point)
295
+ (when (char-or-string-p isearch-project-- thing-at-point)
279
296
(unless (= (point ) (point-max ))
280
297
(forward-char 1 ))
281
298
(forward-symbol -1 )
282
- (isearch-project-isearch-yank-string isearch-project-thing-at-point)))))
299
+ (isearch-project-- isearch-yank-string isearch-project- -thing-at-point)))))
283
300
284
301
(add-hook 'isearch-mode-hook #'isearch-project-isearch-mode-hook )
285
302
0 commit comments