diff --git a/content/commands.js b/content/commands.js index bcbc4dcd..96249130 100644 --- a/content/commands.js +++ b/content/commands.js @@ -186,6 +186,11 @@ function Commands() //{{{ let re = RegExp("[" + list + "]", "g"); return function (str) q + String.replace(str, re, function ($0, $1) $1 in quoteMap ? quoteMap[$1] : "\\" + $1) + q; } + const _quoteArg = { // FIXME + '"': ['"', quote("", '\n\t"\\\\'), '"'], + "'": ["'", quote("", "\\\\'"), "'"], + "": ["", quote("", "\\\\ "), ""] + }; const quoteArg = { '"': quote('"', '\n\t"\\\\'), "'": quote("'", "\\\\'"), @@ -474,7 +479,7 @@ function Commands() //{{{ args.completeOpt = null; args.completeFilter = null; args.completeStart = i; - args.quote = quoteArg[""]; + args.quote = _quoteArg[""]; } if (complete) { @@ -549,7 +554,7 @@ function Commands() //{{{ args.completeStart += optname.length + 1; args.completeOpt = opt; args.completeFilter = arg; - args.quote = quoteArg[quote] || quoteArg[""]; + args.quote = _quoteArg[quote] || _quoteArg[""]; } let type = argTypes[opt[1]]; if (type) @@ -610,7 +615,10 @@ function Commands() //{{{ // if not an option, treat this token as an argument var [count, arg, quote] = getNextArg(sub); if (complete) - args.quote = quoteArg[quote] || quoteArg[""]; + { + args.quote = _quoteArg[quote] || _quoteArg[""]; + args.completeFilter = arg || ""; + } else if (count == -1) { liberator.echoerr("Error parsing arguments: " + arg); @@ -644,14 +652,13 @@ function Commands() //{{{ else compl = opt[3] || []; context.title = [opt[0][0]]; - context.quote = ["", args.quote, ""]; // FIXME + context.quote = args.quote; context.completions = compl; } complete.advance(args.completeStart); complete.title = ["Options"]; if (completeOpts) complete.completions = completeOpts; - } // check for correct number of arguments diff --git a/content/completion.js b/content/completion.js index da32d359..1fb2d962 100644 --- a/content/completion.js +++ b/content/completion.js @@ -55,6 +55,7 @@ function CompletionContext(editor, name, offset) self.offset = parent.offset + (offset || 0); self.keys = util.cloneObject(parent.keys); delete self._generate; + delete self._filter; // FIXME? ["anchored", "compare", "editor", "filterFunc", "keys", "_process", "quote", "title", "top"].forEach(function (key) self[key] = parent[key]); if (self != this) @@ -243,7 +244,9 @@ CompletionContext.prototype = { if (quote) filtered.forEach(function (item) { item.unquoted = item.text; + try { item.text = quote[0] + quote[1](item.text) + quote[2]; + } catch(e) { liberator.dump(quote.map(function (x) <>{util.objectToString(x)})) } }) if (options.get("wildoptions").has("sort")) filtered.sort(this.compare); @@ -309,6 +312,11 @@ CompletionContext.prototype = { advance: function advance(count) { this.offset += count; + if (this.quote) + { + this.quote[0] = ""; + this.quote[2] = ""; + } // XXX if (this._filter) this._filter = this._filter.substr(count); @@ -1197,6 +1205,8 @@ function Completion() //{{{ if (!args.completeOpt && command.completer) { cmdContext.advance(args.completeStart); + cmdContext.quote = args.quote; + cmdContext.filter = args.completeFilter; compObject = command.completer.call(command, cmdContext, args, special, count); if (compObject instanceof Array) // for now at least, let completion functions return arrays instead of objects compObject = { start: compObject[0], items: compObject[1] };