Skip to content

Commit 34e769c

Browse files
authored
fix: Option to determine specific prefixes for quote insertion (#5067)
* add new behaviour option to determine specific prefixes for quote insertion * make quotes check more generic; add auto quote insertion for javascript (backtick) * change cstyle behaviours option to more suitable * add type definition for Mode; move `$pairQuotesAfter` from options to mode property Issue #5063
1 parent 9fcf79a commit 34e769c

File tree

6 files changed

+64
-7
lines changed

6 files changed

+64
-7
lines changed

src/edit_session.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -820,14 +820,19 @@ EditSession.$uid = 0;
820820

821821
this.$modes = config.$modes;
822822

823+
/**
824+
*
825+
* @type {TextMode|null}
826+
*/
827+
this.$mode = null;
828+
this.$modeId = null;
829+
823830
/**
824831
* Sets a new text mode for the `EditSession`. This method also emits the `'changeMode'` event. If a [[BackgroundTokenizer `BackgroundTokenizer`]] is set, the `'tokenizerUpdate'` event is also emitted.
825832
* @param {TextMode} mode Set a new text mode
826-
* @param {cb} optional callback
833+
* @param {Function} cb optional callback
827834
*
828835
**/
829-
this.$mode = null;
830-
this.$modeId = null;
831836
this.setMode = function(mode, cb) {
832837
if (mode && typeof mode === "object") {
833838
if (mode.getTokenizer)

src/mode/behaviour/behaviour_test.js

+22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var XMLMode = require("../xml").Mode;
1818
var HTMLMode = require("../html").Mode;
1919
var CSSMode = require("../css").Mode;
2020
var MarkdownMode = require("../markdown").Mode;
21+
var PythonMode = require("../python").Mode;
2122
var editor;
2223
var exec = function(name, times, args) {
2324
do {
@@ -286,6 +287,16 @@ module.exports = {
286287
exec("insertstring", 1, '`');
287288
exec("insertstring", 1, 'b');
288289
assert.equal(editor.getValue(), "`b`");
290+
291+
editor.setValue("");
292+
exec("insertstring", 1, 'a');
293+
exec("insertstring", 1, "'");
294+
assert.equal(editor.getValue(), "a'");
295+
296+
editor.setValue("");
297+
exec("insertstring", 1, 'b');
298+
exec("insertstring", 1, "`");
299+
assert.equal(editor.getValue(), "b``");
289300
},
290301
"test: css": function() {
291302
editor.session.setMode(new CSSMode());
@@ -393,6 +404,17 @@ module.exports = {
393404
exec("insertstring", 1, "`");
394405
exec("insertstring", 1, "`");
395406
assert.equal(editor.getValue(), "``-``");
407+
},
408+
"test: python": function() {
409+
editor.session.setMode(new PythonMode());
410+
editor.setValue("f", 1);
411+
exec("insertstring", 1, '"');
412+
assert.equal(editor.getValue(), 'f""');
413+
414+
// there is no such prefix for python
415+
editor.setValue("p", 1);
416+
exec("insertstring", 1, '"');
417+
assert.equal(editor.getValue(), 'p"');
396418
}
397419
};
398420

src/mode/behaviour/cstyle.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ var getWrapped = function(selection, selected, opening, closing) {
4646
]
4747
};
4848
};
49-
49+
/**
50+
* Creates a new Cstyle behaviour object with the specified options.
51+
* @constructor
52+
* @param {Object} [options] - The options for the Cstyle behaviour object.
53+
* @param {boolean} [options.braces] - Whether to force braces auto-pairing.
54+
*/
5055
var CstyleBehaviour = function(options) {
5156
this.add("braces", "insertion", function(state, action, editor, session, text) {
5257
var cursor = editor.getCursorPosition();
@@ -260,8 +265,12 @@ var CstyleBehaviour = function(options) {
260265
wordRe.lastIndex = 0;
261266
var isWordBefore = wordRe.test(leftChar);
262267
wordRe.lastIndex = 0;
263-
var isWordAfter = wordRe.test(leftChar);
264-
if (isWordBefore || isWordAfter)
268+
var isWordAfter = wordRe.test(rightChar);
269+
270+
var pairQuotesAfter = session.$mode.$pairQuotesAfter;
271+
var shouldPairQuotes = pairQuotesAfter && pairQuotesAfter[quote] && pairQuotesAfter[quote].test(leftChar);
272+
273+
if ((!shouldPairQuotes && isWordBefore) || isWordAfter)
265274
return null; // before or after alphanumeric
266275
if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
267276
return null; // there is rightChar and it isn't closing

src/mode/javascript.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var CStyleFoldMode = require("./folding/cstyle").FoldMode;
1010

1111
var Mode = function() {
1212
this.HighlightRules = JavaScriptHighlightRules;
13-
13+
1414
this.$outdent = new MatchingBraceOutdent();
1515
this.$behaviour = new CstyleBehaviour();
1616
this.foldingRules = new CStyleFoldMode();
@@ -22,6 +22,9 @@ oop.inherits(Mode, TextMode);
2222
this.lineCommentStart = "//";
2323
this.blockComment = {start: "/*", end: "*/"};
2424
this.$quotes = {'"': '"', "'": "'", "`": "`"};
25+
this.$pairQuotesAfter = {
26+
"`": /\w/
27+
};
2528

2629
this.getNextLineIndent = function(state, line, tab) {
2730
var indent = this.$getIndent(line);

src/mode/python.js

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ oop.inherits(Mode, TextMode);
1616
(function() {
1717

1818
this.lineCommentStart = "#";
19+
this.$pairQuotesAfter = {
20+
"'": /[ruf]/i,
21+
'"': /[ruf]/i
22+
};
1923

2024
this.getNextLineIndent = function(state, line, tab) {
2125
var indent = this.$getIndent(line);

src/mode/text.js

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ var lang = require("../lib/lang");
99
var TokenIterator = require("../token_iterator").TokenIterator;
1010
var Range = require("../range").Range;
1111

12+
/**
13+
*
14+
* @constructor
15+
* @alias TextMode
16+
* @property {{[quote: string]: string}} [$quotes] - quotes used by language mode
17+
* @property {string} lineCommentStart - characters that indicate the start of a line comment
18+
* @property {{start: string, end: string}} [blockComment] - characters that indicate the start and end of a block comment
19+
* @property {TextHighlightRules} HighlightRules - language specific highlighters
20+
* @property {FoldMode} foldingRules - language specific folding rules
21+
* @property {MatchingBraceOutdent} $outdent
22+
* @property {RegExp} tokenRe
23+
* @property {RegExp} nonTokenRe
24+
* @property {{[quote: string]: RegExp}} [$pairQuotesAfter] - An object containing conditions to determine whether to apply matching quote or not.
25+
*/
1226
var Mode = function() {
1327
this.HighlightRules = TextHighlightRules;
1428
};

0 commit comments

Comments
 (0)