X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=common%2Fcontent%2Fabbreviations.js;h=4013be29f68b27361e2b16a6b17b07b5d5d2179c;hb=3d837eb266a3a01d424192aa4ec1a167366178c5;hp=9a76fa372df310d733ca85f6326a66ec501a7730;hpb=eeed0be1a8abf7e3c97f43b63c1d595e940fef21;p=dactyl.git diff --git a/common/content/abbreviations.js b/common/content/abbreviations.js index 9a76fa3..4013be2 100644 --- a/common/content/abbreviations.js +++ b/common/content/abbreviations.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2009 by Martin Stubenschrott // Copyright (c) 2010 by anekos -// Copyright (c) 2010-2011 by Kris Maglione +// Copyright (c) 2010-2012 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -8,6 +8,23 @@ /** @scope modules */ +/** + * A user-defined input mode binding of a typed string to an automatically + * inserted expansion string. + * + * Abbreviations have a left-hand side (LHS) whose text is replaced by that of + * the right-hand side (RHS) when triggered by an Input mode expansion key. + * E.g. an abbreviation with a LHS of "gop" and RHS of "Grand Old Party" will + * replace the former with the latter. + * + * @param {[Mode]} modes The modes in which this abbreviation is active. + * @param {string} lhs The left hand side of the abbreviation; the text to + * be replaced. + * @param {string|function(nsIEditor):string} rhs The right hand side of + * the abbreviation; the replacement text. This may either be a string + * literal or a function that will be passed the appropriate nsIEditor. + * @private + */ var Abbreviation = Class("Abbreviation", { init: function (modes, lhs, rhs) { this.modes = modes.sort(); @@ -15,20 +32,61 @@ var Abbreviation = Class("Abbreviation", { this.rhs = rhs; }, + /** + * Returns true if this abbreviation's LHS and RHS are equal to those in + * *other*. + * + * @param {Abbreviation} other The abbreviation to test. + * @returns {boolean} The result of the comparison. + */ equals: function (other) this.lhs == other.lhs && this.rhs == other.rhs, + /** + * Returns the abbreviation's expansion text. + * + * @param {nsIEditor} editor The editor in which abbreviation expansion is + * occurring. + * @returns {string} + */ expand: function (editor) String(callable(this.rhs) ? this.rhs(editor) : this.rhs), + /** + * Returns true if this abbreviation is defined for all *modes*. + * + * @param {[Mode]} modes The modes to test. + * @returns {boolean} The result of the comparison. + */ modesEqual: function (modes) array.equals(this.modes, modes), + /** + * Returns true if this abbreviation is defined for *mode*. + * + * @param {Mode} mode The mode to test. + * @returns {boolean} The result of the comparison. + */ inMode: function (mode) this.modes.some(function (_mode) _mode == mode), + /** + * Returns true if this abbreviation is defined in any of *modes*. + * + * @param {[Modes]} modes The modes to test. + * @returns {boolean} The result of the comparison. + */ inModes: function (modes) modes.some(function (mode) this.inMode(mode), this), + /** + * Remove *mode* from the list of supported modes for this abbreviation. + * + * @param {Mode} mode The mode to remove. + */ removeMode: function (mode) { this.modes = this.modes.filter(function (m) m != mode).sort(); }, + /** + * @property {string} The mode display characters associated with the + * supported mode combination. + */ get modeChar() Abbreviation.modeChar(this.modes) }, { modeChar: function (_modes) { @@ -45,6 +103,7 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { this._store = {}; }, + /** @property {boolean} True if there are no abbreviations. */ get empty() !values(this._store).nth(util.identity, 0), /** @@ -68,14 +127,15 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { * * @param {Mode} mode The mode of the abbreviation. * @param {string} lhs The LHS of the abbreviation. + * @returns {Abbreviation} The matching abbreviation. */ get: function (mode, lhs) { let abbrevs = this._store[mode]; - return abbrevs && set.has(abbrevs, lhs) ? abbrevs[lhs] : null; + return abbrevs && Set.has(abbrevs, lhs) ? abbrevs[lhs] : null; }, /** - * @property {Abbreviation[]} The list of the abbreviations merged from + * @property {[Abbreviation]} The list of the abbreviations merged from * each mode. */ get merged() { @@ -153,18 +213,18 @@ var Abbreviations = Module("abbreviations", { nonkeyword: /[ "']/ }; - this._match = util.regexp(<>) (+ )$ | // full-id (^ | \s | ) (+ )$ | // end-id (^ | \s ) (\S* )$ // non-id - ]]>, "x", params); - this._check = util.regexp(<>+ | // full-id + | // end-id \S* // non-id ) $ - ]]>, "x", params); + */), "x", params); }, get: deprecated("group.abbrevs.get", { get: function get() this.user.closure.get }), @@ -189,44 +249,42 @@ var Abbreviations = Module("abbreviations", { }, /** - * Lists all abbreviations matching *modes* and *lhs*. + * Lists all abbreviations matching *modes*, *lhs* and optionally *hives*. * * @param {Array} modes List of modes. * @param {string} lhs The LHS of the abbreviation. + * @param {[Hive]} hives List of hives. + * @optional */ - list: function (modes, lhs) { - let hives = contexts.allGroups.abbrevs.filter(function (h) !h.empty); + list: function (modes, lhs, hives) { + let hives = hives || contexts.allGroups.abbrevs.filter(function (h) !h.empty); function abbrevs(hive) hive.merged.filter(function (abbr) (abbr.inModes(modes) && abbr.lhs.indexOf(lhs) == 0)); - let list = - - - - - - - { - template.map(hives, function (hive) let (i = 0) - + - template.map(abbrevs(hive), function (abbrev) - - - - - - ) + - ) - } -
- ModeAbbrevReplacement
{!i++ ? hive.name : ""}{abbrev.modeChar}{abbrev.lhs}{abbrev.rhs}
; - - // TODO: Move this to an ItemList to show this automatically - if (list.*.length() === list.text().length() + 2) - dactyl.echomsg(_("abbrev.none")); - else - commandline.commandOutput(list); + let list = ["table", {}, + ["tr", { highlight: "Title" }, + ["td"], + ["td", { style: "padding-right: 1em;" }, _("title.Mode")], + ["td", { style: "padding-right: 1em;" }, _("title.Abbrev")], + ["td", { style: "padding-right: 1em;" }, _("title.Replacement")]], + ["col", { style: "min-width: 6em; padding-right: 1em;" }], + hives.map(function (hive) let (i = 0) [ + ["tr", { style: "height: .5ex;" }], + abbrevs(hive).map(function (abbrev) + ["tr", {}, + ["td", { highlight: "Title" }, !i++ ? String(hive.name) : ""], + ["td", {}, abbrev.modeChar], + ["td", {}, abbrev.lhs], + ["td", {}, abbrev.rhs]]), + ["tr", { style: "height: .5ex;" }]])]; + + // FIXME? + // // TODO: Move this to an ItemList to show this automatically + // if (list.*.length() === list.text().length() + 2) + // dactyl.echomsg(_("abbreviation.none")); + // else + commandline.commandOutput(list); } }, { @@ -237,7 +295,7 @@ var Abbreviations = Module("abbreviations", { user: contexts.hives.abbrevs.user }); }, - completion: function () { + completion: function initCompletion() { completion.abbreviation = function abbreviation(context, modes, group) { group = group || abbreviations.user; let fn = modes ? function (abbr) abbr.inModes(modes) : util.identity; @@ -245,8 +303,7 @@ var Abbreviations = Module("abbreviations", { context.completions = group.merged.filter(fn); }; }, - - commands: function () { + commands: function initCommands() { function addAbbreviationCommands(modes, ch, modeDescription) { modes.sort(); modeDescription = modeDescription ? " in " + modeDescription + " mode" : ""; @@ -258,14 +315,17 @@ var Abbreviations = Module("abbreviations", { dactyl.assert(!args.length || abbreviations._check.test(lhs), _("error.invalidArgument")); - if (!rhs) - abbreviations.list(modes, lhs || ""); + if (!rhs) { + let hives = args.explicitOpts["-group"] ? [args["-group"]] : null; + abbreviations.list(modes, lhs || "", hives); + } else { if (args["-javascript"]) rhs = contexts.bindMacro({ literalArg: rhs }, "-javascript", ["editor"]); args["-group"].add(modes, lhs, rhs); } }, { + identifier: "abbreviate", completer: function (context, args) { if (args.length == 1) return completion.abbreviation(context, modes, args["-group"]); @@ -286,7 +346,9 @@ var Abbreviations = Module("abbreviations", { command: this.name, arguments: [abbr.lhs], literalArg: abbr.rhs, - options: callable(abbr.rhs) ? {"-javascript": null} : {} + options: { + "-javascript": callable(abbr.rhs) ? null : undefined + } } for ([, abbr] in Iterator(abbreviations.user.merged)) if (abbr.modesEqual(modes)) @@ -301,7 +363,7 @@ var Abbreviations = Module("abbreviations", { if (args.bang) args["-group"].clear(modes); else if (!args["-group"].remove(modes, args[0])) - return dactyl.echoerr(_("abbrev.noSuch")); + return dactyl.echoerr(_("abbreviation.noSuch")); }, { argCount: "?", bang: true, @@ -312,9 +374,10 @@ var Abbreviations = Module("abbreviations", { } addAbbreviationCommands([modes.INSERT, modes.COMMAND_LINE], "", ""); - addAbbreviationCommands([modes.INSERT], "i", "insert"); - addAbbreviationCommands([modes.COMMAND_LINE], "c", "command line"); + [modes.INSERT, modes.COMMAND_LINE].forEach(function (mode) { + addAbbreviationCommands([mode], mode.char, mode.displayName); + }); } }); -// vim: set fdm=marker sw=4 ts=4 et: +// vim: set fdm=marker sw=4 sts=4 ts=8 et: