Override plugin settings per-project via .sublime-project.

Xavura 8 years ago updated by Jonathan Cook 7 years ago 9

I'm aware that .sublime-project files can contain settings but it doesn't appear I can do what I want with them.

Some plugins require per-project settings, at present as far as I can tell this is not possible without resorting to creating and using your own settings file somewhere inside the project path.
It would be very nice if two things could happen:
  1. For settings within the .sublime-project file to overwrite settings from a plugin's settings file, when applicable.
  2. For the API to provide a way to obtain these project-specific settings, which also seems to be impossible at present. Bare in mind that the .sublime-project file may not necessarily be stored within the project path and so we can't just manually walk the project path to search for it.
Both functions would be extremely helpful.
Example: I wrote a command that allows me to browse all gems from the current gem directory and start sublime with the base directory of the selected gem. But the gem directory depends on the ruby version (jruby or MRI ruby) I'm currently using. It would be much nicer if I can store the gem directory setting in the project file.
So it turns out it is possible to do these things, see my reply to the other comment.
I can't tell you the exact setting in use, but overriding plugin settings through project settings should be very much possible - I believe I am doing just that at work. However, my tired brain is getting fuzzy.
For CTags and SublimeGDB, I have per-project settings to set executables and commandlines. The default one is "executable", so that'll never work, and the setup works just fine. Of course, my very tired mind might be messing around with me, and I might be forgetting an important detail.

Let's say my project has a setting called foo, I can get to that via (which I just figured out):


If however foo is not set in the .sublime-project file then that call returns nothing, no matter if foo is set in a plugin somewhere. I would expect it to return the value of foo from the plugin.

This works:

plugin_settings = sublime.load_settings('Plugin.sublime-settings')

foo = sublime.active_window().active_view().settings().get('foo', plugin_settings.get('foo'))

So it IS possible it's just not quite how I personally thought it would work.

Right, so it wasn't just me being high on insomnia... Could've been the case, though.
In case of SublimeGDB, he just if's his way through using .has(), but using the get method with a default value like you did is cleaner (Well, gotta admit that the "sublime.active_window().active_view().settings().get("foo", sublime.load_settings("Plugin.sublime-settings").get("foo"))" construct itself can look pretty confusing too, though. That's waaay to many methods on eachothers tail :P)
Agreed about the chaining, it was just for the sake of example, in practice it shouldn't be quite as bad although it's still a lot of chained method calls.
I hear you regarding the insomnia.

Could you possibly elucidate how to use this to set a project-specific setting for a package? i.e. which file to edit and where to put what? Sorry for the noob question, but I couldn't figure it out from your explanation.


If I am reading the explanation correctly, the two lines of code are placed in the (python?) code of the "plugin".

The standard thing that the plugin is going to be doing is reading in the succession of possible settings files it normally listens for.

If a user goes in and modifies the plugin and adds a reference to the project settings using the chained method calls sublime.active_window().active_view().settings(), they are able to then retrieve settings from a project file when available, falling back to the plugin settings as appropriate.

a better piece of demo code might look more like:

// load up the plugin settings

plugin_settings = sublime.load_settings('Plugin.sublime-settings')

// project plugin settings? sweet! no project plugin settings? ok, well promote plugin_settings up then

project_plugin_settings = sublime.active_window().active_view().settings().get('Plugin', plugin_settings)

// get a plugin settings and fallback on plugin_settings if there's no value in project

// or if there are no project settings at all, it'll check itself twice

foo = project_plugin_settings.get('foo', plugin_settings.get('foo')

if anything is wrong, sorry, I don't normally write python, I'm just looking at the code and cargo culting

the code here:


seems to show that the sublime.active_window().active_view() object is passed as a second parameter at least in the on_post_save event

this plugin is already wired up to get settings from the project file ...