5

Is it possible to make projectile only switch projects when calling projectile-switch-project, and not follow the buffers?

When I switch buffers in emacs, projectile will switch project to the project that the current buffer belong to (if any).

I usually work on a project but have files open from other projects as well. I have an org file with my workitems and notes open (which belongs to my org project) and some test scripts (from my scripts project) and then the source of the project I am working on.

This makes opening files using (helm)-projectile-find-file almost meaningless since I usually have to switch to a buffer from that project first, or do (helm)-projectile-switch-project. And then I can (almost) just as well use helm-find-files.

I still want projectile global mode active though so I can always do C-c p f to open a project file.

  • 1
    If I understood correctly, you want to have an active "main" project and when running projectile-find-file, even in different projects, it should always list file in the "main" project, am I correct? If so, currently it's not implemented but I think it might be useful to toggle a project to be "main". – Tu Do Feb 26 '15 at 17:34
  • Yes, exactly. I was reading the code to see if I could do anything clever with the projectile-switch-project-hook, but couldn't come up with anything. – Niclas W Feb 26 '15 at 19:18
2

In general, projectile commands call projectile-project-root to find the current project, and that works by looking at the current default-directory.

You can advise the project root function and have it return a fixed value instead:

(defvar projectile-main-project "~/projects/foo")

(defun use-main-project (&rest args)
  "Skip calling `projectile-project-root' when there is a main project defined."
  (when projectile-main-project
    projectile-main-project))

(advice-add #'projectile-project-root :before-until #'use-main-project)

This implementation will check to see if projectile-main-project is set and return that. If you set the main project to nil then you'll get the default projectile behavior instead.

Here's a command to change the main project. Note that because we've advised projectile-project-root above, this temporarily unsets the main project to allow projectile to figure out the project for the current buffer, then uses that result.

(defun set-main-project (&optional dir)
  "Set the projectile main project based on the current buffer.
When called with argument DIR, make that main project instead."
  (interactive)
  (if dir
      (setq projectile-main-project dir)
      (let ((current-project))
        (let ((projectile-main-project nil))
          (setq current-project (projectile-project-root)))
        (setq projectile-main-project current-project))))

UPDATE

If you are using a version of Emacs that doesn't have advice-add (older than Emacs 24.4) you can achieve the same result using defadvice instead:

(defadvice projectile-project-root ( around use-main-project activate)
  "Use the current main project, if any."
  (if projectile-main-project
      (setq ad-return-value projectile-main-project)
      ad-do-it))
  • Wonderful! Very nice! Thank you very much. Can I use defadvice or something similar instead? I'm on 24.3. But then again, it would be nice to upgrade =) – Niclas W Feb 26 '15 at 19:41
  • Sure, you could use defadvice instead. In that case you don't have the handy :before-until option, so you would want to use around advice and then explicitly call through the projectile-project-root when there is no main project set. – glucas Feb 26 '15 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.