Some time ago I wrote a post on how to get the current project from within the editor. Today a colleague wondered, whether there is a way of getting the current project from any aspect or any node.

And the answer is: yes, kind of, but not perfect.

First, we need to decide which project we want: the project that “owns” a node, or the project that is associated with the current window that shows the node?

You may have noticed that when you open two projects in MPS they can see each other’s nodes. That’s because MPS loads all the modules and models and nodes from all open projects into a single global repository. And you can use the Go To Node action (Cmd/Ctrl+N) in project A to visit a node from project B.

Which project do you want to get in this case, A or B?

If you want to know the “owning” project (B in our example), Alexander Pann pointed out this method: jetbrains.mps.project.SModuleOperations#getProjectForModule(SModule module). It tries to figure out which project owns a given module and returns this project. (You can get the module of a node via node.model/.getModule().)

This method will work if the module is included in the project directly. For modules from project libraries, plugins, or core modules it will return null.

In some cases this may be good enough. Maybe you just need a repository to run an editor command with and you don’t care much about built-in nodes (they can’t be modified, after all) or nodes being open in projects they don’t belong to.

If you want to know the project associated with the current window (project A), you have a problem: nodes are of course not associated with IDE windows. You have to obtain the project from the context (such as action or editor context) and pass it down to where it is going to be needed.

While less convenient, this solution will work in all cases, including project libraries, plugins, or bundled libraries. It is also going to be more intuitive because the command will be associated with the project window that the user is actively working in, and can be undone in the same project window.