nixos-gui:

- Reduce the number of call the nix-instantiate.
- Improve the option panel, show the name, type, description, value,
example, default value, declarations and definitions files.

svn path=/nixos/trunk/; revision=26951
This commit is contained in:
Nicolas Pierron 2011-04-24 15:30:30 +00:00
parent 66eed7681d
commit 97b39bd17c
4 changed files with 225 additions and 55 deletions

View file

@ -18,13 +18,36 @@ function setProgress(current, max)
function updatePanel(options)
{
log("updatePanel: " + options.length);
var t = "";
for (var i = 0; i < options.length; i++)
{
log("Called with " + options[i].path);
t += options[i].description;
}
$("#option-desc").text(t);
if (options.length == 0)
return;
// FIXME: ignore the rest of the selection for now.
var o = options[0];
$("#name").attr("label", o.path);
if (o.typename != null)
$("#typename").attr("label", o.typename);
else
$("#typename").attr("label", "");
$("#desc").text(o.description);
if (o.value != null)
$("#val").text(o.value);
else
$("#val").text("");
if (o.defaultValue != null)
$("#def").text(o.defaultValue);
else
$("#def").text("");
if (o.example != null)
$("#exp").text(o.example);
else
$("#exp").text("");
$("#decls").text(o.declarations.join("\n"));
$("#defs").text(o.definitions.join("\n"));
}

View file

@ -13,7 +13,7 @@
width = "800"
height = "600"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="jquery-1.3.2.js"/>
<script src="jquery-1.5.2.js"/>
<script src="io.js"/>
<script src="nixos.js"/>
<script src="optionView.js"/>
@ -35,7 +35,25 @@
</tree>
</column>
<column flex="1">
<description id="option-desc" hidden="false"></description>
<caption id="name" label=""/>
<caption id="typename" label=""/>
<separator/>
<description id="desc" hidden="false"></description>
<separator/>
<caption label="Value:"/>
<description id="val" hidden="false"></description>
<separator/>
<caption label="Default:"/>
<description id="def" hidden="false"></description>
<separator/>
<caption label="Example:"/>
<description id="exp" hidden="false"></description>
<separator/>
<caption label="Declarations:"/>
<description id="decls" hidden="false"></description>
<separator/>
<caption label="Definitions:"/>
<description id="defs" hidden="false"></description>
</column>
</columns>
<!-- <progressmeter id="progress-bar" value="0%"/> -->

View file

@ -45,65 +45,78 @@ Option.prototype = {
env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
var out = makeTempFile(this.context_.tmpFile);
var prog = this.context_.instantiateBin + " 2>&1 >" + out.path + " ";
var args = "";
args += " -A eval.options" + (this.path != "" ? "." : "") + this.path;
args += " --eval-only --xml --no-location";
args += " '" + this.context_.root + this.context_.nixos + "'";
var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
var args = " --xml " + this.path;
runProgram(/*env +*/ prog + args);
runProgram(/*env + */ prog + args);
var xml = readFromFile(out);
out.remove(false);
// jQuery does a stack overflow when converting a huge XML to a DOM.
var dom = DOMParser().parseFromString(xml, "text/xml");
var xmlAttrs = $("attr", dom);
var xmlAttrs = $("expr > attrs > attr", dom);
this.isOption = xmlAttrs
.filter (
function (idx) {
return $(this).attr("name") == "_type";
// !!! We could not rely on the value of the attribute because it
// !!! may be unevaluated.
// $(this).children("string[value='option']").length != 0;
})
.length != 0;
this.isOption = xmlAttrs.first().attr("name") == "_isOption";
if (!this.isOption)
{
var cur = this;
var attrs = new Array();
xmlAttrs.each(
function (index) {
var name = $(this).attr("name");
var attr = new Option(name, cur.context_, cur);
attrs.push(attr);
}
);
this.subOptions = attrs;
}
this.loadSubOptions(xmlAttrs);
else
{
this.loadDesc();
// TODO: handle sub-options here.
}
this.loadOption(xmlAttrs);
this.isLoaded = true;
},
loadDesc: function () {
var env = "";
env += "'NIXOS=" + this.context_.root + this.context_.nixos + "' ";
env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
var out = makeTempFile(this.context_.tmpFile);
var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
var args = " -vdl " + this.path;
loadSubOptions: function (xmlAttrs) {
var cur = this;
var attrs = new Array();
runProgram(/*env + */ prog + args);
this.description = readFromFile(out);
out.remove(false);
xmlAttrs.each(
function (index) {
var name = $(this).attr("name");
var attr = new Option(name, cur.context_, cur);
attrs.push(attr);
}
);
this.subOptions = attrs;
},
optionAttributeMap: {
_isOption: function (cur, v) { },
value: function (cur, v) { cur.value = xml2nix($(v).children().first()); },
default: function (cur, v) { cur.defaultValue = xml2nix($(v).children().first()); },
example: function (cur, v) { cur.example = xml2nix($(v).children().first()); },
description: function (cur, v) { cur.description = this.string(v); },
typename: function (cur, v) { cur.typename = this.string(v); },
options: function (cur, v) { cur.loadSubOptions($("attrs", v).children()); },
declarations: function (cur, v) { cur.declarations = this.pathList(v); },
definitions: function (cur, v) { cur.definitions = this.pathList(v); },
string: function (v) {
return $(v).children("string").first().attr("value");
},
pathList: function (v) {
var list = [];
$(v).children("list").first().children().each(
function (idx) {
list.push($(this).attr("value"));
}
);
return list;
}
},
loadOption: function (attrs) {
var cur = this;
attrs.each(
function (index) {
var name = $(this).attr("name");
log("loadOption: " + name);
cur.optionAttributeMap[name](cur, this);
}
);
},
// keep the context under which this option has been used.
@ -111,7 +124,13 @@ Option.prototype = {
// name of the option.
name: "",
// result of nixos-option.
value: null,
typename: null,
defaultValue: null,
example: null,
description: "",
declarations: [],
definitions: [],
// path to reach this option
path: "",
@ -121,6 +140,107 @@ Option.prototype = {
subOptions: []
};
var xml2nix_pptable = {
attrs: function (node, depth, pp) {
var out = "";
out += "{";
var children = node.children().not(
function () {
var name = $(this).attr("name");
return name.charAt(0) == "_";
}
);
if (children.lenght != 0)
{
depth += 1;
children.each(
function (idx) { out += pp.dispatch($(this), depth, pp); }
);
depth -= 1;
out += this.indent(depth) + "";
}
else
out += " ";
out += "}";
return out;
},
list: function (node, depth, pp) {
var out = "";
out += "[";
var children = node.children();
if (children.lenght != 0)
{
depth += 1;
children.each(
function (idx) { out += pp.dispatch($(this), depth, pp); }
);
depth -= 1;
out += this.indent(depth);
}
else
out += " ";
out += "]";
return out;
},
attr: function (node, depth, pp) {
var name = node.attr("name");
var out = "";
var val = "";
out += this.indent(depth);
out += name + " = ";
depth += 1;
val = pp.dispatch(node.children().first(), depth, pp);
out += val;
if (val.indexOf("\n") != -1)
out += this.indent(depth);;
depth -= 1;
out += ";";
return out;
},
string: function (node, depth, pp) {
return "\"" + node.attr("value") + "\"";
},
bool: function (node, depth, pp) {
return node.attr("value");
},
null: function (node, depth, pp) {
return "null";
},
function: function (node, depth, pp) {
return "<function>";
},
unevaluated: function (node, depth, pp) {
return "<unevaluated>";
},
dispatch: function (node, depth, pp) {
for (var key in pp)
{
if(node.is(key))
{
log(this.indent(depth) + "dispatch: " + key);
var out = pp[key](node, depth, pp);
log(this.indent(depth) + "dispatch: => " + out);
return out;
}
}
return "<dispatch-error>";
},
indent: function (depth) {
var ret = "\n";
while (depth--)
ret += " ";
return ret;
}
};
function xml2nix(node) {
var depth = 0;
var pp = xml2nix_pptable;
var out = pp.dispatch(node, depth, pp);
log("pretty:\n" + out);
return out;
}
/*
// Pretty print Nix values.

View file

@ -188,10 +188,19 @@ OptionView.prototype = {
opt.load();
if (opt.isOption)
opts.push(opt);
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
if (opts.lenght != 0)
if (!opts.empty)
this.selCallback(opts);
},