/**
 * Caches wrapping context for current selection in editor
 * @param  {IEmmetEditor} editor 
 * @param  {Object} info Current editor info (content, syntax, etc.) 
 * @return {Object}
 */
function selectionContext(editor, info) {
	info = info || editorUtils.outputInfo(editor);
	return editor.selectionList().map(function (sel, i) {
		var r = range(sel);
		var tag = htmlMatcher.tag(info.content, r.start);
		if (!r.length() && tag) {
			// no selection, use tag pair
			r = utils.narrowToNonSpace(info.content, tag.range);
		}

		var out = {
			selection: r,
			tag: tag,
			caret: r.start,
			syntax: info.syntax,
			profile: info.profile || null,
			counter: i + 1,
			contextNode: actionUtils.captureContext(editor, r.start)
		};

		if (r.length()) {
			var pasted = utils.escapeText(r.substring(info.content));
			out.pastedContent = editorUtils.unindent(editor, pasted);
		}

		return out;
	});
}
	updateTag: function updateTag(editor) {
		var info = editorUtils.outputInfo(editor);
		var selCtx = selectionContext(editor, info);

		// show prompt dialog that will update each
		// tag from selection
		prompt.show({
			label: 'Enter Abbreviation',
			editor: editor.editor,
			editorView: editor.editorView,
			update: function update(abbr) {
				var tag, replaced, delta;
				for (var i = selCtx.length - 1, ctx; i >= 0; i--) {
					ctx = selCtx[i];
					tag = null;

					try {
						tag = _updateTag.getUpdatedTag(abbr, { match: ctx.tag }, info.content, {
							counter: ctx.counter
						});
					} catch (e) {
						console.error(e);
					}

					if (!tag) {
						continue;
					}

					replaced = [{
						start: ctx.tag.open.range.start,
						end: ctx.tag.open.range.end,
						content: tag.source
					}];

					if (tag.name() != ctx.tag.name && ctx.tag.close) {
						replaced.unshift({
							start: ctx.tag.close.range.start,
							end: ctx.tag.close.range.end,
							content: '</' + tag.name() + '>'
						});
					}

					replaced.forEach(function (data) {
						editor.replaceContent(data.content, data.start, data.end);
						ctx.finalCaret = editor.editor.getBuffer().positionForCharacterIndex(data.start);
					});
				}
			},
			confirm: function confirm() {
				setFinalCarets(selCtx, editor.editor);
			}
		});
	}
	expandAbbreviation: function expandAbbreviation(editor) {
		var info = editorUtils.outputInfo(editor);
		var selCtx = editor.selectionList().map(function (sel, i) {
			editor._selection.index = i;
			var r = range(sel);
			return {
				selection: r,
				selectedText: r.substring(info.content),
				caret: r.start,
				syntax: info.syntax,
				profile: info.profile || null,
				counter: i + 1,
				contextNode: actionUtils.captureContext(editor, r.start)
			};
		});

		return this.wrapWithAbbreviation(editor, selCtx);
	},