I am able to get and set the value of Current File Preferences using require('ko/views').current().koDoc.new_line_endings but now I want to add a prefObserverService.addObserver which requires a string value of the property, so new_line_endings I thought, but it doesn’t work. I use the shell to see if I could see it and found 'endOfLine' but that seems to be for the global preference, and koDoc.prefs.getPrefType('new_line_endings') cam back blank. What am I missing (apart from a brain cell or two )?
An example of what I want to do, I believe that 'pleaseObserveMe' is being set on the Current File Preferences.
Why do I want to do this? Well I wanted a more general event for Current File Preferences changed, but I could’t find one or a wya in the wiki https://github.com/Komodo/KomodoEdit/wiki/138-events-and-notifications So this was the idea that I can up with from browsing the source code on GitHub and looking through the Javascript Shell for an appropriate method.
Ok, both syntaxes appear to work for me in the example that I gave above, weird. That aside, assuming that your syntax is correct (thank you), this still doesn’t help me watch for new_line_endings changing. i.e.
This doesn’t work for views.current().koDoc properties (but new_line_endings' is still a Current File Preference) which doesn’t appear to have prefObserverService.addObserver and prefObserverService.removeObserver but it does have methods observerService am I supposed to use that for new_line_endings (i.e. native Current File Preferences) and pref.prefObserverService for my own custom Current File Preferences? I seem to be in the rough vicinity but I’m clearly lost.
I was unable to find the correct string and so went searching the code base and that was what showed up in all examples that I could find relating to what I was doing.
The other related one I needed was/is existing_line_endings. How did you come about lineEndings?
Here’s a quick screen recording, note when I am hovering over the “Line Endings” dropdown I press shift + right mouse button, which brings up DOM inspector. You need to have the following addons installed to do this:
The first line gives me the value from File Preference Settings.
The second gives me false.
The third gives me false.
The last throws hasPref not a function.
Ok, so lineEndings is just the id of the element on the File Preferences dialog, but in the inspector it shows the command that gets called to set the value as setLineEnding(this.value); So, I do a search in the code base for setLineEnding
This leads me to
And the relevant code we have from there is:
var data = {};
data.changedFields = {};
function setField(name, value)
{
data.changedFields[name] = value;
}
function setLineEnding(value) {
if (data.originalLineEnding != "EOL_MIXED") {
var attrValue = (value == data.originalLineEnding).toString();
data.preserveLineEndings.setAttribute("disabled", attrValue);
}
setField('lineEndings', value);
}
function OnPreferencePageClosing(prefset, ok) {
...
case "lineEndings":
var le;
if (value == "EOL_LF") {
le = parent.view.koDoc.EOL_LF;
} else if (value == "EOL_CR") {
le = parent.view.koDoc.EOL_CR;
} else if (value == "EOL_CRLF") {
le = parent.view.koDoc.EOL_CRLF;
}
// If we've changed things, save it as a pref.
if (parent.view.koDoc.new_line_endings != le) {
var eolpref = '';
switch (le) {
case parent.view.koDoc.EOL_LF: eolpref = 'LF'; break;
case parent.view.koDoc.EOL_CR: eolpref = 'CR'; break;
case parent.view.koDoc.EOL_CRLF: eolpref = 'CRLF'; break;
default:
log.error("unknown line ending: " + le);
}
if (eolpref) {
parent.view.prefs.setStringPref('endOfLine', eolpref);
if (parent.view.minimap) {
parent.view.minimap.prefs.setStringPref('endOfLine', eolpref);
}
}
}
// Make the change even if 'le' is unchanged to allow a
// change to "Preserve Line Endings" on EOL_MIXED files to
// correct the file.
parent.view.koDoc.new_line_endings = le;
if (! data.preserveLineEndings.checked) {
// This changes the current document's line endings.
parent.view.koDoc.existing_line_endings = le;
}
...
So the File Prefence is being set at one of the following: parent.view.prefs.setStringPref('endOfLine', eolpref);
or parent.view.minimap.prefs.setStringPref('endOfLine', eolpref);
or parent.view.koDoc.new_line_endings = le;
Now, the first two are strings, and the preference value that I am looking to get is a number, that must mean the relevant line is parent.view.koDoc.new_line_endings = le;
And we’ve already established that I can’t observe new_line_endings
So yep, I lost my fishing pole.
I believe I’m beginning to understand what is going on, and the problem is not to do with the observing, which is where I have been placing my attention. It is beginning to seem that the issue is more to do with the File Preferences dialog not staying in sync with with the actual preferences that have been set. Whether this is a feature or a bug, I do not know. I’m going to create a macro and and video (tomorrow) of what I am seeing and hopefully we can wrap this up.
Most prefs work with observers, meaning that when you change it Komodo catches on and changes things around accordingly. This is not one of those prefs.
So you have to manually do that what the observer is meant to do, in this case you need to set the proper line endings on the document. I’ve revised your userscript to do this:
/*global require, setTimeout */
(function() {
var koDoc = require('ko/views').current().koDoc;
var prefs = require('ko/views').current().prefs;
if ( ! prefs) return;
var listener = {
observe: function (subject, topic, data) {
var current = prefs.getString('endOfLine');
require('ko/dialogs').alert(`Pref changed: ${topic} : ${current}`);
}
};
var setEol = function (value, override)
{
prefs.setString('endOfLine', value);
le = koDoc.EOL_LF;
if (value == "CR")
le = koDoc.EOL_CR;
else if (value == "CRLF")
le = koDoc.EOL_CRLF;
koDoc.new_line_endings = le;
if (override) koDoc.existing_line_endings = le;
}
prefs.prefObserverService.addObserver(
listener,
'endOfLine',
false
);
setEol('LF');
setEol('CRLF', true);
prefs.prefObserverService.removeObserver(
listener,
'endOfLine'
);
}).apply();
Pay special attention to the override flag on setEol, when this is true it replaces the existing line endings.
By the way your selected icons appear to be invisible, you should try deleting profile/XRE/lessCache and profile/XRE/icons while Komodo is not running to flush your caches.
Thanks. Haven’ got around to changing my code to the suggested yet, been looking at a little something else. (no, not porn! )
I wondered about the icons and assumed it was something local to me, just haven’t been that concerned about them. I tried your suggestion of deleting lessCache and icons but they are still the same.
Well that seems to be working well, now that I have a better understanding of this funny fish. Hopefully I can wrap this macro up pretty soon and share it with you (though not sure how useful it is outside of the learning that I have accomplished). Thanks.