Merge pull request #1065 from ajaxorg/selective-bracket-insertion

Selective bracket insertion/skipping for quotes
This commit is contained in:
Harutyun Amirjanyan 2012-11-12 07:41:20 -08:00
commit bd410093d1
3 changed files with 71 additions and 22 deletions

2
build

@ -1 +1 @@
Subproject commit 6149ca6b148e878d4c1341d4675ca3597d78dbdd
Subproject commit 86abb02339499ac96f95649ad5e088e66b6b9a9c

View file

@ -37,10 +37,10 @@ var Range = require("../range").Range;
function BracketMatch() {
this.findMatchingBracket = function(position) {
this.findMatchingBracket = function(position, char) {
if (position.column == 0) return null;
var charBeforeCursor = this.getLine(position.row).charAt(position.column-1);
var charBeforeCursor = char || this.getLine(position.row).charAt(position.column-1);
if (charBeforeCursor == "") return null;
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);

View file

@ -34,10 +34,21 @@ define(function(require, exports, module) {
var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
var lang = require("../../lib/lang");
var SAFE_INSERT_IN_TOKENS =
["text", "paren.rparen", "punctuation.operator"];
var SAFE_INSERT_BEFORE_TOKENS =
["text", "paren.rparen", "punctuation.operator", "comment"];
var autoInsertedBrackets = 0;
var autoInsertedRow = -1;
var autoInsertedLineEnd = "";
var maybeInsertedBrackets = 0;
var maybeInsertedRow = -1;
var maybeInsertedLineStart = "";
var maybeInsertedLineEnd = "";
var CstyleBehaviour = function () {
@ -46,17 +57,17 @@ var CstyleBehaviour = function () {
var iterator = new TokenIterator(session, cursor.row, cursor.column);
// Don't insert in the middle of a keyword/identifier/lexical
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) {
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
// Look ahead in case we're at the end of a token
iterator = new TokenIterator(session, cursor.row, cursor.column + 1);
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"]))
var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
return false;
}
// Only insert in front of whitespace/comments
iterator.stepForward();
return iterator.getCurrentTokenRow() !== cursor.row ||
this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "comment", "paren.rparen"]);
this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
};
CstyleBehaviour.$matchTokenType = function(token, types) {
@ -74,6 +85,17 @@ var CstyleBehaviour = function () {
autoInsertedBrackets++;
};
CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
if (!this.isMaybeInsertedClosing(cursor, line))
maybeInsertedBrackets = 0;
maybeInsertedRow = cursor.row;
maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
maybeInsertedLineEnd = line.substr(cursor.column);
maybeInsertedBrackets++;
};
CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
return autoInsertedBrackets > 0 &&
cursor.row === autoInsertedRow &&
@ -81,12 +103,26 @@ var CstyleBehaviour = function () {
line.substr(cursor.column) === autoInsertedLineEnd;
};
CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
return maybeInsertedBrackets > 0 &&
cursor.row === maybeInsertedRow &&
line.substr(cursor.column) === maybeInsertedLineEnd &&
line.substr(0, cursor.column) == maybeInsertedLineStart;
};
CstyleBehaviour.popAutoInsertedClosing = function() {
autoInsertedLineEnd = autoInsertedLineEnd.substr(1);
autoInsertedBrackets--;
};
CstyleBehaviour.clearMaybeInsertedClosing = function() {
maybeInsertedBrackets = 0;
maybeInsertedRow = -1;
};
this.add("braces", "insertion", function (state, action, editor, session, text) {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
if (text == '{') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
@ -96,15 +132,21 @@ var CstyleBehaviour = function () {
selection: false
};
} else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
CstyleBehaviour.recordAutoInsert(editor, session, "}");
return {
text: '{}',
selection: [1, 1]
};
if (/[\]\}\)]/.test(line[cursor.column])) {
CstyleBehaviour.recordAutoInsert(editor, session, "}");
return {
text: '{}',
selection: [1, 1]
};
} else {
CstyleBehaviour.recordMaybeInsert(editor, session, "{");
return {
text: '{',
selection: [1, 1]
};
}
}
} else if (text == '}') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
@ -117,19 +159,22 @@ var CstyleBehaviour = function () {
}
}
} else if (text == "\n" || text == "\r\n") {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var closing = "";
if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
closing = lang.stringRepeat("}", maybeInsertedBrackets);
CstyleBehaviour.clearMaybeInsertedClosing();
}
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column + 1});
if (rightChar == '}' || closing !== "") {
var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column}, '}');
if (!openBracePos)
return null;
var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString());
var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row));
var indent = this.getNextLineIndent(state, line.substring(0, cursor.column), session.getTabString());
var next_indent = this.$getIndent(line);
return {
text: '\n' + indent + '\n' + next_indent,
text: '\n' + indent + '\n' + next_indent + closing,
selection: [1, indent.length, 1, indent.length]
};
}
@ -144,6 +189,8 @@ var CstyleBehaviour = function () {
if (rightChar == '}') {
range.end.column++;
return range;
} else {
maybeInsertedBrackets--;
}
}
});
@ -243,7 +290,7 @@ var CstyleBehaviour = function () {
var quote = text;
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
if (selected !== "" && selected !== "'" && selected != '"') {
return {
text: quote + selected + quote,
selection: false
@ -278,6 +325,8 @@ var CstyleBehaviour = function () {
// Try and be smart about when we auto insert.
if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
if (!CstyleBehaviour.isSaneInsertion(editor, session))
return;
return {
text: quote + quote,
selection: [1,1]