-
-
Notifications
You must be signed in to change notification settings - Fork 579
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible integration with project.el? #1591
Comments
The only thing I had in mind was adding
As packages like There's not much from I get that it's more convenient to have a single standard, but I also don't think that the fact there's a built-in Emacs package would mean that alternatives packages (especially those much older than it), should be forced to embrace it. On the subject of moving code from Projectile to project.el, there's also the restrictive contribution terms of Emacs which require a contributor agreeement that very few of Projectile's contributors have signed. I think this damn agreement has been a major obsticle for Emacs's upstream attracting more contributors and it's the primary reason I prefer to keep my packages outside of GNU ELPA. A lot time ago Stefan Monnier approached me to discuss adding Projectile to Emacs, but I've turned down this kind proposal because I thought that'd limit a lot the number of Projectile contributors. Btw, you'll also notice that Projectile provides some integration with |
One more thing - I wouldn't say that |
It has been a long time coming. Having
There are a lot of trivial interactive functions in Projectile that now have some counterparts in |
@leungbk FWIW - I've updated the docs to show how easy it is to use As you can see, project detection itself is a tiny part of the work of such a package and it is easy to change with whatever you want. |
@bbatsov This is the other way around. Which is a fine thing to do by itself, I suppose. But I don't understand: do you really not care for the idea of |
It seemed to me like a reasonable approach for someone already using
I guess that's something like
I've been meaning to implement this for a while now, but between all the projects it feel between the cracks. I recall I was looking for some API docs a while back, didn't find any and I forgot about it. I wouldn't mind implementing this in terms of the reference implementation.
That's more or less my take as well. For Projectile to be able to leverage directly some function it will need to contribute its project discovery function to the top of |
I suppose. But there are not many (any?) popular alternative backends for project.el. Some users add their own custom fallback backends, but they can do the same to Projectile, if they wanted, even without this bridge.
Something like. But with a different standard UI and a "replace in all matches" command. It's also "something like"
I'm not sure it makes much sense to provide an alternative default implementation for the generic, but it can work, I suppose.
Not sure why you think it's unlikely. project.el's extensibility was designed with this exact scenario in mind:
|
I'd rather it was automatic, but this should be good too. Thanks! |
Got it. I'll play with it when I get the chance.
You'd probably want to have there
Can you share a link to the default implementation? I'm wondering how exactly are the usages discovered, as I guess if it's not generic you're not really parsing all the code in the project.
Same with Projectile. The API is basically 5 functions and everything else is derived from it.
Given that Projectile and project.el work pretty much the same in this regard - run a list of functions until they get a result, I'm pretty sure the order of the functions can affect the results that users get. :-)
Sure, if that's fine by you I'll just have Projectile register its project function automatically. |
Should be easy to add them, too. As long as they support the necessary flags.
Of course. It's a fallback implementation.
The core can't reference Projectile's functions directly. 🤷♂️
In practice only 1-2 backends will be used on a regular basis. So as long as Projectile is the first item in the list, it should take priority. And as a minor mode, it can be there first. Anyway, that's not the implementation detail I was talking about.
👍 Maybe also add an option for a rare user who'd prefer to opt out or do the integration manually. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding! |
Here's a working implementation. It could be a tad faster if projectile and project.el both used either absolute or relative paths. As it stands we need to do some conversion. I also considered using (require 'cl-lib)
(cl-defmethod project-root ((project (head projectile)))
(cdr project))
(cl-defmethod project-files ((project (head projectile)) &optional dirs)
(let* ((root (project-root project))
;; make paths absolute
(files (mapcar (lambda (f)
(expand-file-name f root))
(projectile-project-files root))))
;; filter out files that don't have the same prefix
(if dirs
(cl-remove-if-not
(lambda (f)
(cl-some (lambda (dir)
(string-prefix-p dir f))
dirs))
files)
files)))
(defun project-projectile (dir)
"Return projectile project of form ('projectile . ROOT-DIR) for DIR"
(let ((root (projectile-project-root dir)))
(when root
(cons 'projectile root))))
(provide 'project-projectile) All you need to do after is (add-hook 'project-find-functions
#'project-projectile
'append) |
Good effort. 👍 A few notes:
|
Thanks for the feedback @dgutov! I didn't know external roots couldn't be subdirs though it makes perfect sense in hindsight. As for no external roots in projectile I guess that explains why the project can be represented as its root alone. Would something like this be welcome as part of projectile then? (require 'cl-lib)
(cl-defmethod project-root ((project (head projectile)))
(cdr project))
(cl-defmethod project-files ((project (head projectile)) &optional dirs)
(let ((root (project-root project)))
;; make paths absolute and ignore the optional dirs argument,
;; see https://github.com/bbatsov/projectile/issues/1591#issuecomment-896423965
(mapcar (lambda (f)
(expand-file-name f root))
(projectile-project-files root))))
(defun project-projectile (dir)
"Return projectile project of form ('projectile . ROOT-DIR) for DIR"
(let ((root (projectile-project-root dir)))
(when root
(cons 'projectile root))))
(provide 'project-projectile) (add-hook 'project-find-functions
#'project-projectile) |
@wurosh For better performance, you might also prefer (cl-defmethod project-files ((project (head projectile)) &optional dirs)
(let ((root (project-root project)))
;; make paths absolute and ignore the optional dirs argument,
;; see https://github.com/bbatsov/projectile/issues/1591#issuecomment-896423965
(mapcar (lambda (f)
(concat root f))
(projectile-project-files root)))) |
And now the ball is in @bbatsov's court. |
Hey! Trying to keep this one alive. It would be indeed a very welcoming addition. A great simplification to thousands of devs out there who would not need to integrate support for both packages. |
I totally forgot about this ticket, but I'll (finally) add this patch to Projectile soon. |
…ile` There are reasons (as I try to keep up with): - I need to work with large projects, and this eats my time, as `project.el` not yet implemented caching functionality. Given that every human being lives the single life, it is not practical to be idealist in such cases. - `project.el` may finally implement caching functionality, and I may switch back there, as this is the only reason I could not use it flawlessly, given "large projects", mentioned above. - there are some points of convergence between `project.el` and `projectile`, so we should give up decent projects handling functionality altogether, if we were purists/idealists/you-name-it, given the initial (political) reason for giving up `projectile` in the past. See bbatsov/projectile#1591 for example. - @bbatsov may change his mind about political situation around Ukraine, which was the reason mentinoned above. But this is highly doubtful, I think.
…ile` There are reasons (as I try to keep up with): - I need to work with large projects, and this eats my time, as `project.el` not yet implemented caching functionality. Given that every human being lives the single life, it is not practical to be idealist in such cases. - `project.el` may finally implement caching functionality, and I may switch back there, as this is the only reason I could not use it flawlessly, given "large projects", mentioned above. - there are some points of convergence between `project.el` and `projectile`, so we should give up decent projects handling functionality altogether, if we were purists/idealists/you-name-it, given the initial (political) reason for giving up `projectile` in the past. See bbatsov/projectile#1591 for example. - @bbatsov may change his mind about political situation around Ukraine, which was the reason mentinoned above. But this is highly doubtful, I think.
…ile` There are reasons (as I try to keep up with): - I need to work with large projects, and this eats my time, as `project.el` not yet implemented caching functionality. Given that every human being lives the single life, it is not practical to be idealist in such cases. - `project.el` may finally implement caching functionality, and I may switch back there, as this is the only reason I could not use it flawlessly, given "large projects", mentioned above. - there are some points of convergence between `project.el` and `projectile`, so we should give up decent projects handling functionality altogether, if we were purists/idealists/you-name-it, given the initial (political) reason for giving up `projectile` in the past. See bbatsov/projectile#1591 for example. - @bbatsov may change his mind about political situation around Ukraine, which was the reason mentinoned above. But this is highly doubtful, I think.
Now that bbatsov/projectile#1282 and bbatsov/projectile#1591 have been addressed in bbatsov/projectile@a0105e7, drop my own code to provide Projectile project root for xref and deadgrep.
…ile` There are reasons (as I try to keep up with): - I need to work with large projects, and this eats my time, as `project.el` not yet implemented caching functionality. Given that every human being lives the single life, it is not practical to be idealist in such cases. - `project.el` may finally implement caching functionality, and I may switch back there, as this is the only reason I could not use it flawlessly, given "large projects", mentioned above. - there are some points of convergence between `project.el` and `projectile`, so we should give up decent projects handling functionality altogether, if we were purists/idealists/you-name-it, given the initial (political) reason for giving up `projectile` in the past. See bbatsov/projectile#1591 for example. - @bbatsov may change his mind about political situation around Ukraine, which was the reason mentinoned above. But this is highly doubtful, I think.
Upstream projectile now enables this integration itself: bbatsov/projectile#1591 (comment)
I recall seeing on Bozhidar's blog a year or two ago that he was interested in integrating
projectile
with Emacs' built-inproject.el
. Packages likedeadgrep
(frontend toripgrep
) are usingproject
exclusively, while some other packages prioritizeprojectile
overproject
in a hard-coded manner, which can lead to some confusion when you're using both types of packages in the same project.It would be nice to see a single custom agreed on by package authors. If there is interest in making
projectile
complementary toproject
, this would entail moving some stuff fromprojectile
toproject
, and/or reusing some ofproject
's utilities inprojectile
The text was updated successfully, but these errors were encountered: