Skip to content

Commit

Permalink
feat(projectile-rails-choices): use all matches
Browse files Browse the repository at this point in the history
Allow regular expressions with more than one match group, and
concatenate them to create the final string.

This is useful for me for finding nested resources with similar paths,
and building short selectors based only on the unique elements.

The best example is finding JS components inside the `app/javascripts`
directory.

The application I work on has two main interfaces, one for
admins, and one for regular consumers. So we have components both
inside the `app/javascripts/admin/components` and
`app/javascripts/consumer/components` directories.

With this change, I can do something like

```elisp
(projectile-rails-find-resource
  "component: "
  '(("app/javascripts/" "/javascripts/\\(.+/\\)components/\\(.+\\).js$")))
```

and this will generate a list like

```
admin/money_input
consumer/money_input
shared/error_container
```
  • Loading branch information
Daniel Ma committed Mar 7, 2019
1 parent 78f5cbe commit 24a2c23
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions projectile-rails.el
Original file line number Diff line number Diff line change
Expand Up @@ -377,19 +377,31 @@ Argument DIR is the directory to which the search should be narrowed."
(substring it (length (projectile-rails-root-relative-to-project-root)))
(projectile-dir-files directory)))

(defun projectile-rails--all-string-matches (regexp string)
"Get all matches from string-match of REGEXP on STRING as a string."
(when (string-match regexp string)
(save-match-data
(let ((match-number 1)
(matched-string "")
(matches '()))
(while (setq matched-string (match-string match-number string))
(push matched-string matches)
(setq match-number (+ match-number 1)))
(mapconcat 'identity (reverse matches) "")))))

(defun projectile-rails-choices (dirs)
"Uses `projectile-rails-dir-files' function to find files in directories.
The DIRS is list of lists consisting of a directory path and regexp to filter files from that directory.
Optional third element can be present in the DIRS list. The third element will be a prefix to be placed before
the filename in the resulting choice.
Returns a hash table with keys being short names (choices) and values being relative paths to the files."
(let ((hash (make-hash-table :test 'equal)))
(let ((hash (make-hash-table :test 'equal)) (matched-string ""))
(loop for (dir re prefix) in dirs do
(loop for file in (projectile-rails-dir-files (projectile-rails-expand-root dir)) do
(when (string-match re file)
(when (setq matched-string (projectile-rails--all-string-matches re file))
(puthash
(concat (or prefix "") (match-string 1 file))
(concat (or prefix "") matched-string)
(concat dir file)
hash))))
hash))
Expand Down

0 comments on commit 24a2c23

Please sign in to comment.