python-rope / ropemode

Common parts of ropemacs and ropevim.
GNU Lesser General Public License v3.0
15 stars 12 forks source link

add rope project autodiscovery #13

Closed noxdafox closed 5 years ago

noxdafox commented 10 years ago

This is a small improvement I use in my ropemode.

I use Rope with Emacs and I usually have several python projects opened at the same time. Every time I switch to a different project or I open a new one I get prompted to the ropeproject location request which is quite irritating.

Such simple code allows Rope Mode to try to discovery the location before asking it to the user. The algorithm is pretty simple: it traverse the project folders from the bottom to up to two folders from the one in which we are working.

I'd like to make such feature configurable so that the user can both decide whether to enable it or not and how many folders upward to look into but I'm not familiar with the whole thing. If you have any suggestion I'd be glad to improve the code snippet.

Something to add in my emacs.d like: (ropemode project-folder-autodiscovery t) (ropemode autodiscovery-depth 2)

mcepl commented 10 years ago

I like this, and actually I was thinking about something similar. @aligrudi , do you see any problem with this?

aligrudi commented 10 years ago

Matěj Cepl notifications@github.com wrote:

I like this, and actually I was thinking about something similar. @aligrudi , do you see any problem with this?

I think it is rather unpredictable; there may be many projects in "./../..". Moreover, "./../.." may be "/"; the search may take a long time and may end up in somebody else's project :^)

Ali
mcepl commented 10 years ago

it traverse the project folders from the bottom to up to two folders from the one in which we are working.

@aligrudi you seem to miss this line.

aligrudi commented 10 years ago

Matěj Cepl notifications@github.com wrote:

it traverse the project folders from the bottom to up to two folders from the one in which we are working.

@aligrudi you seem to miss this line.

Of course this is only my personal opinion: it should be possible to define the behaviour of a command precisely for it to be actually useful. This command may select a directory, not even a parent of the CWD or it may select an arbitrary directory under the CWD.

I think most of the time one wishes to find the project containing the file being edited, as ropemode already does. The use case I am thinking about is this: one opens a python file, decides to perform a refactoring (or perform code completion), and, no project being open, decides to open the smallest existing project containing the file.

diff --git a/ropemode/interface.py b/ropemode/interface.py index 0e617c9..505332b 100644 --- a/ropemode/interface.py +++ b/ropemode/interface.py @@ -78,10 +78,28 @@ def exiting_actions(self): if self.project is not None: self.close_project()

  • def _find_project(self):
  • root = os.curdir +
  • TODO: allow to configure the search depth

  • for _ in range(2):
  • root = os.path.join(root, os.pardir) +
  • for root, dirs, files in os.walk(top=os.pardir, topdown=False):
  • if [f for f in files if f.endswith('.py')]:

Also note that the local variable root is initialised here, but it is not used afterwards and os.pardir is passed to os.walk(). So the patch starts searching from the parent directory.

Ali
noxdafox commented 10 years ago

The algorithm explores the directory tree from the leaves to the root, thus it is impossible for ropemode to get to the wrong .ropeproject folder. The only feasible scenario is when the user hasn't created any project folder yet and the search depth is greater than the project's root folder. This is why I would like to make the value configurable to fulfil different users' needs. In my case a search depth of 2 is good enough as I always have a similar project layout:

. project_name .. src ... setup.py ... project_root

But the majority of the Python projects have a different layout: . project_name .. setup.py .. project_root Which would require a depth of 1.

For the performance concerns: I am using this code snippet in my daily work and I haven't noticed any issue so far even with large projects.

noxdafox commented 10 years ago

I investigated further in the logic and fixed a couple of things:

  1. My assumption that the current working directory is the one where the inspected file belongs was wrong, now the function actually gets the current directory properly.
  2. The os.walk was getting as top directory the parent directory instead of the root one, copy pasted from old code.

I couldn't spot the error nr1 as most of my projects already have a ropeproject folder so the function was just picking up the wrong ones. Now it should be more robust.

mcepl commented 9 years ago

I will take a look at this. Let me test it for a while and I will see how it works in practice.

mcepl commented 9 years ago

So, I have started to use ropemode (underneatch Ropevim) with this pull request and it behaves weird:

a) How do you actually start new Rope project? Of course, plain RopeOpenProject doesn’t work, what is even worse it seems that Rope somehow found a project “behind the corner” (I have rather complicated network of symlinks but in the end I would like to be in ~/archiv/2015/projekty/something and Rope thinks, when using commands like RopeProjectConfig, that it is in ~/archiv/2015/projekty/elsewhere). b) Even when I copy .ropeproject from an existing project, Rope somehow still holds to its ideé fix that of the project behind the corner.

noxdafox commented 9 years ago

I use emacs and the new rope project is started by ropemacs when a python file is opened.

My emacs layout has changed quite much since this pull request so I cannot easily test it anymore but I can explain the logic behind it.

Once a python file is opened I get from the environment the path of the file and I use its location as a crawling starting point.

I crawl all the directories from the bottom one to the top one up to the configured limit (hardcoded as 2 at the moment). If I hit the limit and I don't find any project I default to the old logic prompting the user to specify the path in which the ropeproject is.

Of course the algorithm doesn't consider symlinks but I guess it could easily do it.

mcepl commented 9 years ago

I don't know what to do about this pull request:

However, it is hard to tell without knowing the rest of the stack you use. To make it complete solution, could I ask you to provide your ~/.emacs changes to https://github.com/python-rope/ropemacs as well? (BTW, most of us being stupid vimers, don't know anything about the glorious world of Emacs, so if you could help with maintaining ropemacs, we would be very much grateful).

noxdafox commented 9 years ago

The issue you're suffering from is not due to vim but to the way your projects are probably organised. Proof is that you automatically get a .ropeproject loaded but a wrong one.

Could you please show me the directory tree you're using in your test?

To see where the algorithm walks just add a print curdir just after the for loop, it will print the path it's exploring.

Regarding emacs, well... yes you "stupid vimers" should see the light :p

Does it make sense to maintain ropemacs? Have you seen the efforts of this project? https://github.com/abingham/traad

That's the right direction imho.

mcepl commented 9 years ago

See https://bugzilla.redhat.com/show_bug.cgi?id=916561#c0 ~/projekty which contains all projects is a symlink to ~/Dokumenty/projekt (note, that ~/Dokumenty is itself a symlink to ~/archiv/2015 this year).

aligrudi commented 9 years ago

Matěj Cepl notifications@github.com wrote:

I don't know what to do about this pull request:

  • on the one hand, I really like the idea. I don't think user should care about the mechanism behind the rope and I don't think they should even know there are some metadata stored and where they are stored (hmm, shouldn't we even add automatically .ropeproject/ to .git/info/exclude, @aligrudi )?

Personally, I prefer defining a global .gitignore (HOME/.config/git/ignore or using "git config --global core.excludesfile HOME/.gitignore").

  • on the other hand, quite frankly, this doesn't work for me. I guess I am missing something in ropevim to make it work.

I do not think the patch is general enough:

glyph commented 5 years ago

I am a bit lost on whether this issue is current... is this something that still needs to be fixed? However I have ropemacs configured it seems to find and open the appropriate project for some years now. I don’t see anything obviously relevant in my .emacs.d, but it’s pretty huge so I could be mistaken…

Basically I’m wondering if this (the last open PR on this project!) should be closed.

soupytwist commented 5 years ago

Agreed, this has been lingering for 5 years, think it's time to close it.