ActiveState Community

Where does Komodo store the file preferences?

Posted by jgold on 2009-09-28 16:17
OS: All / Any

The tab preferences in Komodo are a little confusing. I've changed the options in the edit->preferences option for indentation to prefer tabs over spaces. The only problem is that it doesn't seem to change files that already exist. I have to go into each tab, right click on it and choose "Properties and settings" and then change the tab options there as well.

There are a lot file files so I was hoping to automate it a bit. It doesn't look like Komodo is saving those settings in the actual .py file and I didn't find them in the project file. Is there someplace else it might be storing those settings?

Thanks.

ericp | Mon, 2009-09-28 17:22

(function() {
function update() {
    var gprefs = Components.classes["@activestate.com/koPrefService;1"].getService(Components.interfaces.koIPrefService).prefs
    var langPrefs = gprefs.getPref('languages');
    var specificLangPrefs, docPrefs;
    var langSettings = {};
    var obj;
    var views = ko.views.manager.topView.getViewsByType(true, "editor");
    for (var view, i = 0; view = views[i]; i++) {
        var document = view.document;
        var lang = document.language;
        if (!(lang in langSettings)) {
            try {
                specificLangPrefs = langPrefs.getPref('languages/' + lang);
                obj = {
                    indentWidth: specificLangPrefs.getLongPref('indentWidth'),
                    useTabs: specificLangPrefs.getBooleanPref('useTabs')
                };
                langSettings[lang] = obj;
            } catch(ex) {
                dump("updateIndentation failed getting prefs: " + ex + "\n");
                continue;
            }
        } else {
            obj = langSettings[lang];
        }
        try {
            docPrefs = document.prefs;
            docPrefs.setLongPref('indentWidth', obj['indentWidth']);
            docPrefs.setBooleanPref('useTabs', obj['useTabs']);
        } catch(ex) {
            dump("updateIndentation failed setting prefs: " + ex + "\n");
        }
    }
}
try {
    update();
} catch(ex) {
    dump("update failed: " + ex + "\n");
}
})();
(function() {
function update() {
    var gprefs = Components.classes["@activestate.com/koPrefService;1"].getService(Components.interfaces.koIPrefService).prefs
    var langPrefs = gprefs.getPref('languages');
    var specificLangPrefs, docPrefs;
    var langSettings = {};
    var obj;
    var views = ko.views.manager.topView.getViewsByType(true, "editor");
    for (var view, i = 0; view = views[i]; i++) {
        var document = view.document;
        var lang = document.language;
        if (!(lang in langSettings)) {
            try {
                specificLangPrefs = langPrefs.getPref('languages/' + lang);
                obj = {
                    indentWidth: specificLangPrefs.getLongPref('indentWidth'),
                    useTabs: specificLangPrefs.getBooleanPref('useTabs')
                };
                langSettings[lang] = obj;
            } catch(ex) {
                dump("updateIndentation failed getting prefs: " + ex + "\n");
                continue;
            }
        } else {
            obj = langSettings[lang];
        }
        try {
            docPrefs = document.prefs;
            docPrefs.setLongPref('indentWidth', obj['indentWidth']);
            docPrefs.setBooleanPref('useTabs', obj['useTabs']);
        } catch(ex) {
            dump("updateIndentation failed setting prefs: " + ex + "\n");
        }
    }
}
try {
    update();
} catch(ex) {
    dump("update failed: " + ex + "\n");
}
})();

There's a good question whether this should be the default, or not. This
is a good place to hold that discussion....

- Eric

jgold | Tue, 2009-09-29 09:46

Wow! Thank Eric. I didn't mean for anyone to spend that kind of time on it but I do appreciate it.

As far as the tab behavior goes, I would think that the easiest way would be for the default setting when a new file is created would be to use the project settings. That way if you change the project settings it would automatically change all the files in the project since they're looking at the default by default ;). If you manually change a specific file to use something other than the default, that would change it for that file permanently or until it's manually changed back.

At least that's how I would suspect it to work. Since I never set the individual file properties, I thought they would always follow the project settings but they don't. It was a bit confusing.

ericp | Tue, 2009-09-29 09:50

From there it took about ten minutes to add the pref handling. The
amazing thing was that it worked the first time, and the macro
looks worth keeping.

Note that even if we were to add an "update indentation on opened files"
feature, previous opened files would still have their old indentation
setting when they get reopened.

Here's an idea using the other kind of tab -- the tab with the filename
at the top of the editor window: when the document uses different
indentation settings from its language, color the tab differently.

- Eric

jgold | Tue, 2009-09-29 15:18

What I was thinking is that by default, the individual files have a setting that tells them to get the preferred indentation setting from the project or the Komodo system wide settings. With that as he default, changing the project or preferences would change all the existing files unless you've manually set them to something else. It obviates the need to have an "update indentation on opened files" function. They would always inherent the system settings unless manually changed.

That doesn't exclude the idea of having a different tab color if the indentation differs from the project settings. You could do both.

Before switching over to Komodo, I was a Wing IDE user. It has an indentation tool that tells you if the file you're viewing is indented with tabs, spaces or mixed. It also has a button that will convert all the tabs. I actually installed it and used it to convert all my existing space indented files to tab indented. I only did that because I couldn't find a similar utility in Komodo to convert them.

Since then, I found that once you set the preferences the way you want, you can select all the lines and hit the tab key. That will add a tab to every line but it also converts all the existing indents to whatever the preferences are set to. Hitting the shift tab key removes the extra indent. It has the same effect as the Wing utility.

ericp | Tue, 2009-09-29 17:02

First, when you load a new file into Komodo, it analyzes the indentation
usage in the file, to determine what the settings should be (unless you
tell it not to). We assume that usually you don't want to change the
indentation on a file, so once we've determined it, we lock it down.
That way, you can change the global indentation setting without having
to worry about settings for existing files.

However, Komodo is quite flexible. Using a post-file-open trigger, you
can duplicate the behavior you're used to. It will take a bit of digging
in the Komodo API -- I recommend you hang out at the
http://community.activestate.com/addons forum -- there are some very
knowledgeable people there who can help you grapple with the API.

To get you started, here's a post-file-open trigger-macro that checks
the indentation on newly opened files, and colors the file's tab
if its indentation settings are out of line with the global setting.
There are three things still missing:

1. Watching for a change in the document's indentation settings, and
updating the tab color if needed.

2. Watching for a change in the global and language indentation settings...

3. Providing a control that will let you tell Komodo to restore the tab to
the default color, and skip this file. I would add a menu item to the
tab's context menu to make this happen.

All of this is doable via Komodo macros -- no need to write an extension.

Macro:

try {
    var view = ((typeof(subject) != "undefined" && subject)
                ? subject : ko.views.manager.currentView);
    var doc = view.document;
    var lang = doc.language;
    var gprefs = Components.classes["@activestate.com/koPrefService;1"].getService(Components.interfaces.koIPrefService).prefs
    var specificLangPrefs = gprefs.getPref('languages').getPref('languages/' + lang);
    var langSettings = {
                indentWidth: specificLangPrefs.getLongPref('indentWidth'),
                useTabs: specificLangPrefs.getBooleanPref('useTabs')
    };
    var docPrefs = doc.prefs;
    var docSettings =  {
                indentWidth: docPrefs.getLongPref('indentWidth'),
                useTabs: docPrefs.getBooleanPref('useTabs')
    };
    if (docSettings.indentWidth != langSettings.indentWidth
        || docSettings.useTabs != langSettings.useTabs) {
        view.parentNode._tab.style.cssText = "background-color: rgb(247, 212, 242)";
    }
   
    //TODO: Add an observer on this document pref -- if its indentation
    // changes to match the language's, set the
    // background-color to rgb(197, 212, 242)
} catch(ex) {
    alert(ex + "\n");
}
try {
    var view = ((typeof(subject) != "undefined" && subject)
                ? subject : ko.views.manager.currentView);
    var doc = view.document;
    var lang = doc.language;
    var gprefs = Components.classes["@activestate.com/koPrefService;1"].getService(Components.interfaces.koIPrefService).prefs
    var specificLangPrefs = gprefs.getPref('languages').getPref('languages/' + lang);
    var langSettings = {
                indentWidth: specificLangPrefs.getLongPref('indentWidth'),
                useTabs: specificLangPrefs.getBooleanPref('useTabs')
    };
    var docPrefs = doc.prefs;
    var docSettings =  {
                indentWidth: docPrefs.getLongPref('indentWidth'),
                useTabs: docPrefs.getBooleanPref('useTabs')
    };
    if (docSettings.indentWidth != langSettings.indentWidth
        || docSettings.useTabs != langSettings.useTabs) {
        view.parentNode._tab.style.cssText = "background-color: rgb(247, 212, 242)";
    }
    
    //TODO: Add an observer on this document pref -- if its indentation
    // changes to match the language's, set the
    // background-color to rgb(197, 212, 242)
} catch(ex) {
    alert(ex + "\n");
}