better folding commands
This commit is contained in:
parent
150f0360d4
commit
d689636771
7 changed files with 161 additions and 42 deletions
|
|
@ -35,12 +35,13 @@ var lang = require("../lib/lang");
|
||||||
var config = require("../config");
|
var config = require("../config");
|
||||||
|
|
||||||
function bindKey(win, mac) {
|
function bindKey(win, mac) {
|
||||||
return {
|
return {win: win, mac: mac};
|
||||||
win: win,
|
|
||||||
mac: mac
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
multiSelectAction: "forEach"|"forEachLine"|function|undefined,
|
||||||
|
scrollIntoView: true|"cursor"|"center"|"selectionPart"
|
||||||
|
*/
|
||||||
exports.commands = [{
|
exports.commands = [{
|
||||||
name: "showSettingsMenu",
|
name: "showSettingsMenu",
|
||||||
bindKey: bindKey("Ctrl-,", "Command-,"),
|
bindKey: bindKey("Ctrl-,", "Command-,"),
|
||||||
|
|
@ -75,21 +76,46 @@ exports.commands = [{
|
||||||
name: "fold",
|
name: "fold",
|
||||||
bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
|
bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
|
||||||
exec: function(editor) { editor.session.toggleFold(false); },
|
exec: function(editor) { editor.session.toggleFold(false); },
|
||||||
|
scrollIntoView: "center",
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}, {
|
}, {
|
||||||
name: "unfold",
|
name: "unfold",
|
||||||
bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
|
bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
|
||||||
exec: function(editor) { editor.session.toggleFold(true); },
|
exec: function(editor) { editor.session.toggleFold(true); },
|
||||||
|
scrollIntoView: "center",
|
||||||
|
readOnly: true
|
||||||
|
}, {
|
||||||
|
name: "toggleFoldWidget",
|
||||||
|
bindKey: bindKey("F2", "F2"),
|
||||||
|
exec: function(editor) { editor.session.toggleFoldWidget(); },
|
||||||
|
scrollIntoView: "center",
|
||||||
|
readOnly: true
|
||||||
|
}, {
|
||||||
|
name: "toggleParentFoldWidget",
|
||||||
|
bindKey: bindKey("Alt-F2", "Alt-F2"),
|
||||||
|
exec: function(editor) { editor.session.toggleFoldWidget(true); },
|
||||||
|
scrollIntoView: "center",
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}, {
|
}, {
|
||||||
name: "foldall",
|
name: "foldall",
|
||||||
bindKey: bindKey("Alt-0", "Command-Option-0"),
|
bindKey: bindKey("Ctrl-Alt-0", "Ctrl-Command-Option-0"),
|
||||||
exec: function(editor) { editor.session.foldAll(); },
|
exec: function(editor) { editor.session.foldAll(); },
|
||||||
|
scrollIntoView: "center",
|
||||||
|
readOnly: true
|
||||||
|
}, {
|
||||||
|
name: "foldOther",
|
||||||
|
bindKey: bindKey("Alt-0", "Command-Option-0"),
|
||||||
|
exec: function(editor) {
|
||||||
|
editor.session.foldAll();
|
||||||
|
editor.session.unfold(editor.selection.getAllRanges());
|
||||||
|
},
|
||||||
|
scrollIntoView: "center",
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}, {
|
}, {
|
||||||
name: "unfoldall",
|
name: "unfoldall",
|
||||||
bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
|
bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
|
||||||
exec: function(editor) { editor.session.unfold(); },
|
exec: function(editor) { editor.session.unfold(); },
|
||||||
|
scrollIntoView: "center",
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}, {
|
}, {
|
||||||
name: "findnext",
|
name: "findnext",
|
||||||
|
|
@ -125,6 +151,7 @@ exports.commands = [{
|
||||||
bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
|
bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
|
||||||
exec: function(editor) { editor.navigateFileStart(); },
|
exec: function(editor) { editor.navigateFileStart(); },
|
||||||
multiSelectAction: "forEach",
|
multiSelectAction: "forEach",
|
||||||
|
scrollIntoView: "cursor",
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
group: "fileJump"
|
group: "fileJump"
|
||||||
}, {
|
}, {
|
||||||
|
|
@ -345,7 +372,8 @@ exports.commands = [{
|
||||||
name: "togglecomment",
|
name: "togglecomment",
|
||||||
bindKey: bindKey("Ctrl-/", "Command-/"),
|
bindKey: bindKey("Ctrl-/", "Command-/"),
|
||||||
exec: function(editor) { editor.toggleCommentLines(); },
|
exec: function(editor) { editor.toggleCommentLines(); },
|
||||||
multiSelectAction: "forEachLine"
|
multiSelectAction: "forEachLine",
|
||||||
|
scrollIntoView: "selectionPart"
|
||||||
}, {
|
}, {
|
||||||
name: "toggleBlockComment",
|
name: "toggleBlockComment",
|
||||||
bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
|
bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
|
||||||
|
|
@ -439,26 +467,31 @@ exports.commands = [{
|
||||||
name: "outdent",
|
name: "outdent",
|
||||||
bindKey: bindKey("Shift-Tab", "Shift-Tab"),
|
bindKey: bindKey("Shift-Tab", "Shift-Tab"),
|
||||||
exec: function(editor) { editor.blockOutdent(); },
|
exec: function(editor) { editor.blockOutdent(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEach",
|
||||||
|
scrollIntoView: "selectionPart"
|
||||||
}, {
|
}, {
|
||||||
name: "indent",
|
name: "indent",
|
||||||
bindKey: bindKey("Tab", "Tab"),
|
bindKey: bindKey("Tab", "Tab"),
|
||||||
exec: function(editor) { editor.indent(); },
|
exec: function(editor) { editor.indent(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEach",
|
||||||
},{
|
scrollIntoView: "selectionPart"
|
||||||
|
}, {
|
||||||
name: "blockoutdent",
|
name: "blockoutdent",
|
||||||
bindKey: bindKey("Ctrl-[", "Ctrl-["),
|
bindKey: bindKey("Ctrl-[", "Ctrl-["),
|
||||||
exec: function(editor) { editor.blockOutdent(); },
|
exec: function(editor) { editor.blockOutdent(); },
|
||||||
multiSelectAction: "forEachLine"
|
multiSelectAction: "forEachLine",
|
||||||
},{
|
scrollIntoView: "selectionPart"
|
||||||
|
}, {
|
||||||
name: "blockindent",
|
name: "blockindent",
|
||||||
bindKey: bindKey("Ctrl-]", "Ctrl-]"),
|
bindKey: bindKey("Ctrl-]", "Ctrl-]"),
|
||||||
exec: function(editor) { editor.blockIndent(); },
|
exec: function(editor) { editor.blockIndent(); },
|
||||||
multiSelectAction: "forEachLine"
|
multiSelectAction: "forEachLine",
|
||||||
|
scrollIntoView: "selectionPart"
|
||||||
}, {
|
}, {
|
||||||
name: "insertstring",
|
name: "insertstring",
|
||||||
exec: function(editor, str) { editor.insert(str); },
|
exec: function(editor, str) { editor.insert(str); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEach",
|
||||||
|
scrollIntoView: "cursor"
|
||||||
}, {
|
}, {
|
||||||
name: "inserttext",
|
name: "inserttext",
|
||||||
exec: function(editor, args) {
|
exec: function(editor, args) {
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,18 @@ function Folding() {
|
||||||
return foundFolds;
|
return foundFolds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getFoldsInRangeList = function(ranges) {
|
||||||
|
if (Array.isArray(ranges)) {
|
||||||
|
var folds = [];
|
||||||
|
ranges.forEach(function(range) {
|
||||||
|
folds = folds.concat(this.getFoldsInRange(range));
|
||||||
|
}, this);
|
||||||
|
} else {
|
||||||
|
var folds = this.getFoldsInRange(ranges);
|
||||||
|
}
|
||||||
|
return folds;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns all folds in the document
|
* Returns all folds in the document
|
||||||
*/
|
*/
|
||||||
|
|
@ -273,7 +285,7 @@ function Folding() {
|
||||||
|
|
||||||
// --- Some checking ---
|
// --- Some checking ---
|
||||||
if (!(startRow < endRow ||
|
if (!(startRow < endRow ||
|
||||||
startRow == endRow && startColumn <= endColumn - 2))
|
startRow == endRow && startColumn < endColumn - 2))
|
||||||
throw new Error("The range has to be at least 2 characters width");
|
throw new Error("The range has to be at least 2 characters width");
|
||||||
|
|
||||||
var startFold = this.getFoldAt(startRow, startColumn, 1);
|
var startFold = this.getFoldAt(startRow, startColumn, 1);
|
||||||
|
|
@ -442,7 +454,7 @@ function Folding() {
|
||||||
else
|
else
|
||||||
range = location;
|
range = location;
|
||||||
|
|
||||||
folds = this.getFoldsInRange(range);
|
folds = this.getFoldsInRangeList(range);
|
||||||
if (expandInner) {
|
if (expandInner) {
|
||||||
this.removeFolds(folds);
|
this.removeFolds(folds);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -450,7 +462,7 @@ function Folding() {
|
||||||
// expandFolds several times.
|
// expandFolds several times.
|
||||||
while (folds.length) {
|
while (folds.length) {
|
||||||
this.expandFolds(folds);
|
this.expandFolds(folds);
|
||||||
folds = this.getFoldsInRange(range);
|
folds = this.getFoldsInRangeList(range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -636,17 +648,16 @@ function Folding() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var range = this.getFoldWidgetRange(row);
|
var range = this.getFoldWidgetRange(row);
|
||||||
var rangeEndRow = range.end.row;
|
|
||||||
// sometimes range can be incompatible with existing fold
|
// sometimes range can be incompatible with existing fold
|
||||||
// TODO change addFold to return null istead of throwing
|
// TODO change addFold to return null istead of throwing
|
||||||
if (range && range.isMultiLine()
|
if (range && range.isMultiLine()
|
||||||
&& rangeEndRow <= endRow
|
&& range.end.row <= endRow
|
||||||
&& range.start.row >= startRow
|
&& range.start.row >= startRow
|
||||||
) try {
|
) try {
|
||||||
var fold = this.addFold("...", range);
|
var fold = this.addFold("...", range);
|
||||||
fold.collapseChildren = depth;
|
fold.collapseChildren = depth;
|
||||||
// addFold can change the range
|
// addFold can change the range
|
||||||
row = rangeEndRow;
|
row = range.end.row;
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -727,25 +738,34 @@ function Folding() {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onFoldWidgetClick = function(row, e) {
|
this.onFoldWidgetClick = function(row, e) {
|
||||||
|
e = e.domEvent;
|
||||||
|
var options = {
|
||||||
|
children: e.shiftKey,
|
||||||
|
all: e.ctrlKey || e.metaKey,
|
||||||
|
siblings: e.altKey
|
||||||
|
};
|
||||||
|
|
||||||
|
var range = this.$toggleFoldWidget(row, options);
|
||||||
|
if (!range)
|
||||||
|
(e.target || e.srcElement).className += " ace_invalid";
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$toggleFoldWidget = function(row, options) {
|
||||||
var type = this.getFoldWidget(row);
|
var type = this.getFoldWidget(row);
|
||||||
var line = this.getLine(row);
|
var line = this.getLine(row);
|
||||||
e = e.domEvent;
|
|
||||||
var children = e.shiftKey;
|
|
||||||
var all = e.ctrlKey || e.metaKey;
|
|
||||||
var siblings = e.altKey;
|
|
||||||
|
|
||||||
var dir = type === "end" ? -1 : 1;
|
var dir = type === "end" ? -1 : 1;
|
||||||
var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
|
var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
|
||||||
|
|
||||||
if (fold) {
|
if (fold) {
|
||||||
if (children || all)
|
if (options.children || options.all)
|
||||||
this.removeFold(fold);
|
this.removeFold(fold);
|
||||||
else
|
else
|
||||||
this.expandFold(fold);
|
this.expandFold(fold);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var range = this.getFoldWidgetRange(row);
|
var range = this.getFoldWidgetRange(row, true);
|
||||||
// sometimes singleline folds can be missed by the code above
|
// sometimes singleline folds can be missed by the code above
|
||||||
if (range && !range.isMultiLine()) {
|
if (range && !range.isMultiLine()) {
|
||||||
fold = this.getFoldAt(range.start.row, range.start.column, 1);
|
fold = this.getFoldAt(range.start.row, range.start.column, 1);
|
||||||
|
|
@ -755,24 +775,48 @@ function Folding() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (siblings) {
|
if (options.siblings) {
|
||||||
var data = this.getParentFoldRangeData(row);
|
var data = this.getParentFoldRangeData(row);
|
||||||
if (data.range) {
|
if (data.range) {
|
||||||
var startRow = data.range.start.row + 1;
|
var startRow = data.range.start.row + 1;
|
||||||
var endRow = data.range.end.row;
|
var endRow = data.range.end.row;
|
||||||
}
|
}
|
||||||
this.foldAll(startRow, endRow, all ? 10000 : 0);
|
this.foldAll(startRow, endRow, options.all ? 10000 : 0);
|
||||||
} else if (children) {
|
} else if (options.children) {
|
||||||
var endRow = range ? range.end.row : this.getLength();
|
endRow = range ? range.end.row : this.getLength();
|
||||||
this.foldAll(row + 1, range.end.row, all ? 10000 : 0);
|
this.foldAll(row + 1, range.end.row, options.all ? 10000 : 0);
|
||||||
} else if (range) {
|
} else if (range) {
|
||||||
if (all)
|
if (options.all)
|
||||||
range.collapseChildren = 10000;
|
range.collapseChildren = 10000;
|
||||||
this.addFold("...", range);
|
this.addFold("...", range);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!range)
|
return range;
|
||||||
(e.target || e.srcElement).className += " ace_invalid"
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.toggleFoldWidget = function(toggleParent) {
|
||||||
|
var row = this.selection.getCursor().row;
|
||||||
|
row = this.getRowFoldStart(row);
|
||||||
|
var range = this.$toggleFoldWidget(row, {});
|
||||||
|
|
||||||
|
if (range)
|
||||||
|
return;
|
||||||
|
// handle toggleParent
|
||||||
|
var data = this.getParentFoldRangeData(row, true);
|
||||||
|
range = data.range || data.firstRange;
|
||||||
|
|
||||||
|
if (range) {
|
||||||
|
row = range.start.row;
|
||||||
|
var fold = this.getFoldAt(row, this.getLine(row).length, 1);
|
||||||
|
|
||||||
|
if (fold) {
|
||||||
|
this.removeFold(fold);
|
||||||
|
} else {
|
||||||
|
this.addFold("...", range);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateFoldWidgets = function(e) {
|
this.updateFoldWidgets = function(e) {
|
||||||
|
|
|
||||||
|
|
@ -1643,8 +1643,8 @@ var Editor = function(renderer, session) {
|
||||||
var range = this.getSelectionRange().collapseRows();
|
var range = this.getSelectionRange().collapseRows();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
first: range.start.row,
|
first: this.session.getRowFoldStart(range.start.row),
|
||||||
last: range.end.row
|
last: this.session.getRowFoldEnd(range.end.row)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ oop.inherits(FoldMode, BaseFoldMode);
|
||||||
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
|
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
|
||||||
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
|
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
|
||||||
|
|
||||||
this.getFoldWidgetRange = function(session, foldStyle, row) {
|
this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
|
||||||
var line = session.getLine(row);
|
var line = session.getLine(row);
|
||||||
var match = line.match(this.foldingStartMarker);
|
var match = line.match(this.foldingStartMarker);
|
||||||
if (match) {
|
if (match) {
|
||||||
|
|
@ -61,7 +61,16 @@ oop.inherits(FoldMode, BaseFoldMode);
|
||||||
if (match[1])
|
if (match[1])
|
||||||
return this.openingBracketBlock(session, match[1], row, i);
|
return this.openingBracketBlock(session, match[1], row, i);
|
||||||
|
|
||||||
return session.getCommentFoldRange(row, i + match[0].length, 1);
|
var range = session.getCommentFoldRange(row, i + match[0].length, 1);
|
||||||
|
|
||||||
|
if (range && !range.isMultiLine()) {
|
||||||
|
if (forceMultiline) {
|
||||||
|
range = this.getSectionRange(session, row);
|
||||||
|
} else if (foldStyle != "all")
|
||||||
|
range = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foldStyle !== "markbeginend")
|
if (foldStyle !== "markbeginend")
|
||||||
|
|
@ -78,6 +87,37 @@ oop.inherits(FoldMode, BaseFoldMode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getSectionRange = function(session, row) {
|
||||||
|
var line = session.getLine(row);
|
||||||
|
var startIndent = line.search(/\S/);
|
||||||
|
var startRow = row;
|
||||||
|
var startColumn = line.length;
|
||||||
|
row = row + 1;
|
||||||
|
var endRow = row;
|
||||||
|
var maxRow = session.getLength();
|
||||||
|
while (++row < maxRow) {
|
||||||
|
line = session.getLine(row);
|
||||||
|
var indent = line.search(/\S/);
|
||||||
|
if (indent === -1)
|
||||||
|
continue;
|
||||||
|
if (startIndent > indent)
|
||||||
|
break;
|
||||||
|
var subRange = this.getFoldWidgetRange(session, "all", row);
|
||||||
|
|
||||||
|
if (subRange) {
|
||||||
|
if (subRange.isMultiLine()) {
|
||||||
|
row = subRange.end.row;
|
||||||
|
} else if (startIndent == indent) {
|
||||||
|
endRow = row - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endRow = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
|
||||||
|
};
|
||||||
|
|
||||||
}).call(FoldMode.prototype);
|
}).call(FoldMode.prototype);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ var FoldMode = exports.FoldMode = function() {};
|
||||||
|
|
||||||
var fw = session.foldWidgets[end.row];
|
var fw = session.foldWidgets[end.row];
|
||||||
if (fw == null)
|
if (fw == null)
|
||||||
fw = this.getFoldWidget(session, end.row);
|
fw = session.getFoldWidget(end.row);
|
||||||
|
|
||||||
if (fw == "start" && end.row > start.row) {
|
if (fw == "start" && end.row > start.row) {
|
||||||
end.row --;
|
end.row --;
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,11 @@ var TextMode = require("./text").Mode;
|
||||||
var Tokenizer = require("../tokenizer").Tokenizer;
|
var Tokenizer = require("../tokenizer").Tokenizer;
|
||||||
var ShHighlightRules = require("./sh_highlight_rules").ShHighlightRules;
|
var ShHighlightRules = require("./sh_highlight_rules").ShHighlightRules;
|
||||||
var Range = require("../range").Range;
|
var Range = require("../range").Range;
|
||||||
|
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
|
||||||
|
|
||||||
var Mode = function() {
|
var Mode = function() {
|
||||||
this.HighlightRules = ShHighlightRules;
|
this.HighlightRules = ShHighlightRules;
|
||||||
|
this.foldingRules = new CStyleFoldMode();
|
||||||
};
|
};
|
||||||
oop.inherits(Mode, TextMode);
|
oop.inherits(Mode, TextMode);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ function FoldHandler(editor) {
|
||||||
var range = data.range || data.firstRange;
|
var range = data.range || data.firstRange;
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
var row = range.start.row;
|
row = range.start.row;
|
||||||
var fold = session.getFoldAt(row, session.getLine(row).length, 1);
|
var fold = session.getFoldAt(row, session.getLine(row).length, 1);
|
||||||
|
|
||||||
if (fold) {
|
if (fold) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue