Merge pull request +13073 from c9/ide-file-tree

fix issues with file tree
pull/282/head
Harutyun Amirjanyan 2016-03-30 11:55:16 +04:00
commit 7eb38be6c6
10 zmienionych plików z 346 dodań i 158 usunięć

Wyświetl plik

@ -127,10 +127,20 @@ exports.trimTrailingSpace = function(session, options) {
var lines = doc.getAllLines(); var lines = doc.getAllLines();
var min = options && options.trimEmpty ? -1 : 0; var min = options && options.trimEmpty ? -1 : 0;
var cursors = session.selection.rangeCount var cursors = [], ci = -1;
? session.selection.ranges.map(function(x) { return x.cursor; }) if (options && options.keepCursorPosition) {
: [session.selection.getCursor()]; if (session.selection.rangeCount) {
var ci = options && options.keepCursorPosition ? 0 : -1; session.selection.rangeList.ranges.forEach(function(x, i, ranges) {
var next = ranges[i + 1]
if (next && next.cursor.row == x.cursor.row)
return;
cursors.push(x.cursor);
});
} else {
cursors.push(session.selection.getCursor());
}
ci = 0;
}
var cursorRow = cursors[ci] && cursors[ci].row; var cursorRow = cursors[ci] && cursors[ci].row;
for (var i = 0, l=lines.length; i < l; i++) { for (var i = 0, l=lines.length; i < l; i++) {
@ -139,7 +149,7 @@ exports.trimTrailingSpace = function(session, options) {
if (i == cursorRow) { if (i == cursorRow) {
if (index < cursors[ci].column) if (index < cursors[ci].column)
index = min; index = cursors[ci].column;
ci++; ci++;
cursorRow = cursors[ci] ? cursors[ci].row : -1; cursorRow = cursors[ci] ? cursors[ci].row : -1;
} }

Wyświetl plik

@ -1,13 +1,14 @@
if (typeof process !== "undefined") { if (typeof process !== "undefined") {
require("amd-loader"); require("amd-loader");
require("../test/mockdom");
} }
define(function(require, exports, module) { define(function(require, exports, module) {
"use strict"; "use strict";
require("../multi_select");
var assert = require("assert"); var assert = require("assert");
var EditSession = require("../edit_session").EditSession; var EditSession = require("../edit_session").EditSession;
var UndoManager = require("../undomanager").UndoManager;
var whitespace = require("./whitespace"); var whitespace = require("./whitespace");
// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite // Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite
@ -111,8 +112,79 @@ module.exports = {
assert.equal(indent.length, 1); assert.equal(indent.length, 1);
next(); next();
} },
"test trimTrailingSpace": function(next) {
var session = new EditSession([
"a",
"\t b \t",
" ",
"\t",
"\t\tx\t\t",
" ",
" "
]);
session.setUndoManager(new UndoManager());
function testOne(value, options) {
console.log(JSON.stringify(session.getValue()))
whitespace.trimTrailingSpace(session, options);
assert.equal(value, session.getValue());
session.markUndoGroup();
session.getUndoManager().undo();
}
testOne("a\n\t b\n \n\t\n\t\tx\n \n ")
testOne("a\n\t b\n\n\n\t\tx\n\n", {
trimEmpty: true
});
session.selection.fromJSON([{
start: {row:2,column:3},
end: {row:4,column:4}
}]);
testOne("a\n\t b\n\n\n\t\tx\t\n\n", {
keepCursorPosition: true,
trimEmpty: true
});
session.selection.fromJSON([{
start: {row:2,column:3},
end: {row:4,column:4},
isBackwards: true
}]);
testOne("a\n\t b\n \n\n\t\tx\n\n", {
keepCursorPosition: true,
trimEmpty: true
});
session.selection.$initRangeList();
session.selection.fromJSON([{
start: {row:2, column:3},
end: {row:2,column:3}
}, {
start: {row:1, column:1},
end: {row:1, column:1}
}, {
start: {row:2,column:2},
end: {row:2,column:2}
}, {
start: {row:0,column:5},
end: {row:0,column:5},
isBackwards:false
}, {
start: {row:6,column:1},
end: {row:6,column:1},
isBackwards:false
}]);
testOne("a\n\t b\n \n\n\t\tx\n\n ", {
trimEmpty: true,
keepCursorPosition: true
});
next();
},
}; };
}); });

Wyświetl plik

@ -49,7 +49,7 @@ var DataProvider = function(root) {
}; };
this.open = this.open =
this.expand = function(node, deep, silent, justLoaded) { this.expand = function(node, deep, silent) {
if (typeof deep != "number") if (typeof deep != "number")
deep = deep ? 100 : 0; deep = deep ? 100 : 0;
if (!node) if (!node)
@ -69,7 +69,7 @@ var DataProvider = function(root) {
this.collapse(node, null, true); this.collapse(node, null, true);
node.status = "loaded"; node.status = "loaded";
if (!err) if (!err)
this.expand(node, null, false, true); this.expand(node, null, false);
}.bind(this)); }.bind(this));
this.setOpen(node, true); this.setOpen(node, true);
return; return;
@ -95,9 +95,6 @@ var DataProvider = function(root) {
} }
} }
if (justLoaded)
node.justLoaded = true;
this.rows = items.length; this.rows = items.length;
silent || this._signal("expand", node); silent || this._signal("expand", node);
}; };

Wyświetl plik

@ -157,11 +157,12 @@ var EditableTree = function(tree) {
this.ace.commands.bindKeys({ this.ace.commands.bindKeys({
"Esc": function(ace) { "Esc": function(ace) {
ace.treeEditor.endRename(true); ace.treeEditor.endRename(true);
ace.treeEditor.tree.focus();
}, },
"Enter": function(ace) { "Enter": function(ace) {
ace.treeEditor.endRename(); ace.treeEditor.endRename();
ace.treeEditor.tree.focus(); },
"ctrl-s|cmd-s": function(ace) {
ace.treeEditor.endRename();
}, },
"Tab": function(ace) { "Tab": function(ace) {
ace.treeEditor.editNext(1); ace.treeEditor.editNext(1);
@ -249,17 +250,24 @@ var EditableTree = function(tree) {
this._destroyEditor = function() { this._destroyEditor = function() {
if (this.lastDomNode) { if (this.lastDomNode) {
this.lastDomNode.style.color = ""; this.lastDomNode.style.color = "";
this.lastDomNode this.lastDomNode;
} }
this.ace.off("blur", this._onBlur); this.ace.off("blur", this._onBlur);
this.tree.renderer.off("afterRender", this._onAfterRender); this.tree.renderer.off("afterRender", this._onAfterRender);
this.ace.blur();
this.ace.destroy(); var ace = this.ace;
if (this.ace.wrapper.parentNode)
this.ace.wrapper.parentNode.removeChild(this.ace.wrapper);
this.ace = null; this.ace = null;
ace.renderer.freeze();
setTimeout(function() {
// doing this after timeout to allow rename event focus something else
var wasFocused = ace.isFocused();
ace.destroy();
if (ace.wrapper.parentNode)
ace.wrapper.parentNode.removeChild(ace.wrapper);
if (wasFocused)
this.tree.focus();
}.bind(this));
}; };
this.findNextEditPoint = function(dir, node, col, keepColumn) { this.findNextEditPoint = function(dir, node, col, keepColumn) {
@ -378,16 +386,18 @@ var EditableTree = function(tree) {
var val = this.ace.getValue(); var val = this.ace.getValue();
this._destroyEditor();
if (!cancel && this.origVal !== val) { if (!cancel && this.origVal !== val) {
this.tree._emit("rename", { this.tree._emit("rename", {
node: node, node: node,
value: val, value: val,
oldValue: this.origVal,
column: this.column column: this.column
}); });
this.tree.provider._signal("change"); this.tree.provider._signal("change");
} }
this._destroyEditor();
}; };
}).call(EditableTree.prototype); }).call(EditableTree.prototype);

11
node_modules/vfs-local/localfs.js wygenerowano vendored
Wyświetl plik

@ -1032,7 +1032,16 @@ module.exports = function setup(fsOptions) {
if (!exists || options.overwrite || isSamePath) { if (!exists || options.overwrite || isSamePath) {
// Rename the file // Rename the file
fs.rename(frompath, topath, function (err) { fs.rename(frompath, topath, function (err) {
if (err) return callback(err); if (err) {
if (err.code == 'ENOENT' && options.mkdirP != false) {
options.mkdirP = false;
return mkdirP(dir, {}, function(err) {
if (err) return callback(err);
rename(path, options, callback);
});
}
return callback(err);
}
// Rename metadata // Rename metadata
if (options.metadata !== false) { if (options.metadata !== false) {

Wyświetl plik

@ -55,7 +55,7 @@
"c9" "c9"
], ],
"c9plugins": { "c9plugins": {
"c9.ide.language": "#6d5a10ac4f", "c9.ide.language": "#ebc064ef16",
"c9.ide.language.css": "#be07d72209", "c9.ide.language.css": "#be07d72209",
"c9.ide.language.generic": "#92210f5a48", "c9.ide.language.generic": "#92210f5a48",
"c9.ide.language.html": "#22fdc74869", "c9.ide.language.html": "#22fdc74869",
@ -116,7 +116,7 @@
"c9.ide.theme.flat": "#81dadeee55", "c9.ide.theme.flat": "#81dadeee55",
"c9.ide.threewaymerge": "#229382aa0b", "c9.ide.threewaymerge": "#229382aa0b",
"c9.ide.undo": "#b028bcb4d5", "c9.ide.undo": "#b028bcb4d5",
"c9.ide.upload": "#0bd010d3dc", "c9.ide.upload": "#a3da59803d",
"c9.ide.welcome": "#5b86c44e92", "c9.ide.welcome": "#5b86c44e92",
"c9.ide.guide": "#8ab966f344" "c9.ide.guide": "#8ab966f344"
} }

Wyświetl plik

@ -82,6 +82,9 @@ define(function(require, exports, module) {
node.status = "pending"; node.status = "pending";
return; return;
} }
var parentPath = e.path;
if (!parentPath.endsWith("/"))
parentPath += "/";
// update cache // update cache
if (!node) { if (!node) {
if (!showHidden && isFileHidden(e.path)) if (!showHidden && isFileHidden(e.path))
@ -92,97 +95,116 @@ define(function(require, exports, module) {
orphans[e.path] = node; orphans[e.path] = node;
orphan = true; orphan = true;
} }
node.$lastReadT = Date.now();
// Indicate this directory has been fully read // Indicate this directory has been fully read
model.setAttribute(node, "status", "loaded"); model.setAttribute(node, "status", "loaded");
var wasOpen = startUpdate(node); var ondisk = Object.create(null);
node.children = null; var toRemove = [];
var existing = node.map || {}; var toCreate = [];
node.map = {}; var orphanAppand = [];
var existing = node.map || (node.map = Object.create(null));
// Fill Parent
var ondisk = {}, toAppend = [];
e.result[1].forEach(function(stat) { e.result[1].forEach(function(stat) {
if (!stat.name || !showHidden && isFileHidden(stat.name)) if (!stat.name || !showHidden && isFileHidden(stat.name))
return; return;
var name = stat.name; var name = stat.name;
var path = (e.path + "/" + name).replace("//", "/"); var path = parentPath + name;
ondisk[name] = 1; ondisk[name] = 1;
// if (existing[name]) return;
if (orphans[path]) { if (orphans[path]) {
toAppend.push(path); if (existing[name])
delete orphans[path];
orphanAppand.push(path);
} }
createNode(path, stat, existing[name], true);
if (existing[name])
updateNodeStat(path, stat, existing[name]);
else
toCreate.push(stat);
}); });
for (var name in existing) { Object.keys(existing).forEach(function(name) {
if (!ondisk[name]) { // onreaddir can be called before copied nodes are written to disk
// onreaddir can be called before copied nodes are written to disk // in this case we don't want to lose "predicted" state
// in this case we don't want to lose "predicted" state if (existing[name] && existing[name].status === "predicted")
if (existing[name] && existing[name].status === "predicted") ondisk[name] = 1;
node.map[name] = existing[name]; if (!ondisk[name])
else { toRemove.push(name);
delete existing[name]; });
emit("remove", { if (!toCreate.length && !toRemove.length && !orphanAppand.length)
path: e.path + "/" + name, return;
node: existing[name],
parent: node var wasOpen = startUpdate(node);
}); node.children = null;
}
} // Fill Parent
} toCreate.forEach(function(stat) {
createNode(parentPath + stat.name, stat, null, true);
});
toRemove.forEach(function(name) {
var currentNode = existing[name];
delete existing[name];
emit("remove", {
path: parentPath + name,
node: currentNode,
parent: node
});
});
emit("readdir", { path : e.path, parent : node, orphan: orphan }); emit("readdir", { path : e.path, parent : node, orphan: orphan });
endUpdate(node, wasOpen); endUpdate(node, wasOpen);
toAppend.forEach(function(path) { orphanAppand.forEach(function(path) {
emit("orphan-append", {path: path}); emit("orphan-append", {path: path});
}); });
} }
fs.on("afterReaddir", onreaddir, plugin); fs.on("afterReaddir", onreaddir, plugin);
function onstat(e) { function onstat(e) {
var stat; if (e.error) return;
if (!e.error) { // update cache
// update cache var stat = e.result[1];
var there = true;
var node = findNode(e.path); var there = true;
var parent = findNode(dirname(e.path)); var node = findNode(e.path);
var parent = findNode(dirname(e.path));
if (!showHidden && isFileHidden(e.path))
return; if (!showHidden && isFileHidden(e.path))
return;
if (!node) { if (!node) {
if (!parent) if (!parent)
return; return;
there = false; there = false;
}
if (there != !!stat) {
if (there) {
if (!node.link)
deleteNode(node);
} }
else {
if (there != !!e.result[1]) {
if (there) {
if (!node.link)
deleteNode(node);
}
else {
stat = e.result[1];
if (typeof stat != "object")
stat = null;
createNode(e.path, stat);
}
}
else if (there) {
stat = e.result[1];
if (typeof stat != "object") if (typeof stat != "object")
stat = null; stat = null;
createNode(e.path, stat, node); createNode(e.path, stat);
} }
} }
else if (there) {
if (typeof stat != "object")
stat = null;
if (!stat && node)
return;
if (stat && node)
updateNodeStat(e.path, stat, node);
else
createNode(e.path, stat, node);
}
} }
fs.on("afterStat", onstat, plugin); fs.on("afterStat", onstat, plugin);
fs.on("afterReadFile", function(e) { fs.on("afterReadFile", function(e) {
@ -295,14 +317,15 @@ define(function(require, exports, module) {
// Validation // Validation
var toNode = findNode(newPath); var toNode = findNode(newPath);
deleteNode(node, true); if (!toNode) {
if (toNode) deleteNode(node, true);
deleteNode(toNode, true); createNode(newPath, null, node); // Move node
recurPathUpdate(node, oldPath, newPath);
createNode(newPath, null, node); // Move node }
recurPathUpdate(node, oldPath, newPath);
e.undo = function(){ e.undo = function(){
if (toNode)
return;
if (!parent) { if (!parent) {
var tmpParent = node; var tmpParent = node;
while (node.parent && tmpParent.parent.status == "pending") while (node.parent && tmpParent.parent.status == "pending")
@ -318,6 +341,12 @@ define(function(require, exports, module) {
recurPathUpdate(node, newPath, oldPath); recurPathUpdate(node, newPath, oldPath);
}; };
e.confirm = function() { e.confirm = function() {
if (toNode) {
deleteNode(toNode, true);
createNode(newPath, null, node); // Move node
recurPathUpdate(node, oldPath, newPath);
}
if (node.status === "predicted") if (node.status === "predicted")
node.status = "loaded"; node.status = "loaded";
}; };
@ -511,14 +540,8 @@ define(function(require, exports, module) {
updateNode = orphans[path]; updateNode = orphans[path];
delete orphans[path]; delete orphans[path];
} }
var original_stat;
if (stat && stat.link) {
original_stat = stat;
stat = stat.linkStat;
}
var parts = path.split("/"); var parts = path.split("/");
var name = parts[parts.length - 1];
var node = model.root.map[parts[0] == "~" ? "~" : ""]; var node = model.root.map[parts[0] == "~" ? "~" : ""];
if (!node) { if (!node) {
node = orphans[parts[0]]; node = orphans[parts[0]];
@ -537,7 +560,7 @@ define(function(require, exports, module) {
var map = node.map; var map = node.map;
if (!map) { if (!map) {
map = node.map = {}; map = node.map = Object.create(null);
} }
parent = node; parent = node;
node = map[p]; node = map[p];
@ -545,6 +568,11 @@ define(function(require, exports, module) {
modified.push(parent); modified.push(parent);
if (i !== parts.length - 1) { if (i !== parts.length - 1) {
node = {label: p, path: subPath, status: "pending", isFolder: true}; node = {label: p, path: subPath, status: "pending", isFolder: true};
// TODO filter hidden files in getChildren instead.
if (!showHidden && isFileHidden(p)) {
orphans[node.path] = path;
return;
}
} else if (updateNode) { } else if (updateNode) {
deleteNode(updateNode, true); deleteNode(updateNode, true);
node = updateNode; node = updateNode;
@ -564,8 +592,32 @@ define(function(require, exports, module) {
node = {label: parts[parts.length - 1], path: path}; node = {label: parts[parts.length - 1], path: path};
orphans[path] = node; orphans[path] = node;
} }
updateNodeStat(path, stat, node);
node.children = null;
if (!updating) {
if (!modified.length)
modified.push(parent);
var wasOpen = startUpdate(modified[0]);
modified.forEach(function(n) {
if (n != model.root)
n.children = null;
});
endUpdate(modified[0], wasOpen);
}
model._signal("createNode", node);
return node;
}
function updateNodeStat(path, stat, node) {
node.path = path; node.path = path;
var original_stat;
if (stat && stat.link) {
original_stat = stat;
stat = stat.linkStat;
}
if (stat) { if (stat) {
var isFolder = stat && /(directory|folder)$/.test(stat.mime); var isFolder = stat && /(directory|folder)$/.test(stat.mime);
if (isFolder) { if (isFolder) {
@ -589,25 +641,13 @@ define(function(require, exports, module) {
delete node.isFolder; delete node.isFolder;
} }
if (node.isFolder && !node.map) if (node.isFolder && !node.map) {
node.map = {}; node.map = Object.create(null);
else if (!node.isFolder && node.map) node.children = null;
} else if (!node.isFolder && node.map) {
delete node.map; delete node.map;
node.children = null;
node.children = null;
if (!updating) {
if (!modified.length)
modified.push(parent);
var wasOpen = startUpdate(modified[0]);
modified.forEach(function(n) {
if (n != model.root)
n.children = null;
});
endUpdate(modified[0], wasOpen);
} }
model._signal("createNode", node);
return node;
} }
function deleteNode(node, silent) { function deleteNode(node, silent) {
@ -670,7 +710,7 @@ define(function(require, exports, module) {
map: {} map: {}
}; };
var root = {}; var root = {};
root.map = {}; root.map = Object.create(null);
root.map[""] = model.projectDir; root.map[""] = model.projectDir;
model.setRoot(root); model.setRoot(root);
// fs.readdir("/", function(){}); // fs.readdir("/", function(){});
@ -894,7 +934,12 @@ define(function(require, exports, module) {
* @param {Function} progress * @param {Function} progress
* @param {Function} done * @param {Function} done
*/ */
loadNodes: loadNodes loadNodes: loadNodes,
/**
* @ignore
*/
isFileHidden: isFileHidden
}); });
register(null, { register(null, {

Wyświetl plik

@ -54,7 +54,7 @@ define(function(require, module, exports) {
var gotYesNo = false; var gotYesNo = false;
plugin.once("hide", function(){ plugin.once("hide", function(){
!gotYesNo && cancel && onNo(false, true, metadata); !gotYesNo && cancel && onNo && onNo(false, true, metadata);
}); });
plugin.update([ plugin.update([
@ -63,22 +63,22 @@ define(function(require, module, exports) {
{ id: "yestoall", visible: all, onclick: function(){ { id: "yestoall", visible: all, onclick: function(){
gotYesNo = true; gotYesNo = true;
plugin.hide(); plugin.hide();
onYes(true, metadata); onYes && onYes(true, metadata);
}}, }},
{ id: "notoall", visible: all, onclick: function(){ { id: "notoall", visible: all, onclick: function(){
gotYesNo = true; gotYesNo = true;
plugin.hide(); plugin.hide();
onNo(true, false, metadata); onNo && onNo(true, false, metadata);
}}, }},
{ id: "yes", onclick: function(){ { id: "yes", onclick: function(){
gotYesNo = true; gotYesNo = true;
plugin.hide(); plugin.hide();
onYes(false, metadata); onYes && onYes(false, metadata);
}}, }},
{ id: "no", onclick: function(){ { id: "no", onclick: function(){
gotYesNo = true; gotYesNo = true;
plugin.hide(); plugin.hide();
onNo(false, false, metadata); onNo && onNo(false, false, metadata);
}} }}
]); ]);
}, options.queue === false); }, options.queue === false);

Wyświetl plik

@ -3,7 +3,7 @@ define(function(require, exports, module) {
"Panel", "c9", "util", "fs", "settings", "ui", "menus", "Panel", "c9", "util", "fs", "settings", "ui", "menus",
"panels", "commands", "tabManager", "fs.cache", "watcher", "panels", "commands", "tabManager", "fs.cache", "watcher",
"preferences", "clipboard", "dialog.alert", "dialog.fileremove", "preferences", "clipboard", "dialog.alert", "dialog.fileremove",
"dialog.fileoverwrite", "dialog.error", "layout" "dialog.fileoverwrite", "dialog.error", "layout", "dialog.question"
]; ];
main.provides = ["tree"]; main.provides = ["tree"];
return main; return main;
@ -24,6 +24,7 @@ define(function(require, exports, module) {
var watcher = imports.watcher; var watcher = imports.watcher;
var prefs = imports.preferences; var prefs = imports.preferences;
var alert = imports["dialog.alert"].show; var alert = imports["dialog.alert"].show;
var question = imports["dialog.question"].show;
var fsCache = imports["fs.cache"]; var fsCache = imports["fs.cache"];
var confirmRemove = imports["dialog.fileremove"].show; var confirmRemove = imports["dialog.fileremove"].show;
var confirmRename = imports["dialog.fileoverwrite"].show; var confirmRename = imports["dialog.fileoverwrite"].show;
@ -34,7 +35,7 @@ define(function(require, exports, module) {
var TreeEditor = require("ace_tree/edit"); var TreeEditor = require("ace_tree/edit");
var markup = require("text!./tree.xml"); var markup = require("text!./tree.xml");
var basename = require("path").basename; var join = require("path").join;
var dirname = require("path").dirname; var dirname = require("path").dirname;
var staticPrefix = options.staticPrefix; var staticPrefix = options.staticPrefix;
@ -52,7 +53,7 @@ define(function(require, exports, module) {
}); });
var emit = plugin.getEmitter(); var emit = plugin.getEmitter();
var container, winFilesViewer; //UI elements var container, winFilesViewer; // UI elements
var showHideScrollPos, scrollTimer; var showHideScrollPos, scrollTimer;
var tree; var tree;
@ -404,15 +405,10 @@ define(function(require, exports, module) {
emit("expand", { path: id }); emit("expand", { path: id });
if (node.justLoaded) {
delete node.justLoaded;
return;
}
// Only save if we are not loading the tree // Only save if we are not loading the tree
if (!refreshing || loadedSettings != -1) { if (!refreshing || loadedSettings != -1) {
if (!node.isRoot) { if (!node.isRoot) {
var refresh = !refreshing && node.status == "loaded"; var refresh = !refreshing && node.status == "loaded" && Date.now() - node.$lastReadT > 500;
watcher.watch(id, refresh); watcher.watch(id, refresh);
// watch children // watch children
@ -424,8 +420,10 @@ define(function(require, exports, module) {
}); });
} }
changed = true; if (!updateSingleDirectoryChain(true, node)) {
settings.save(); changed = true;
settings.save();
}
} }
}, plugin); }, plugin);
@ -451,13 +449,28 @@ define(function(require, exports, module) {
}); });
} }
changed = true; if (!updateSingleDirectoryChain(false, node)) {
settings.save(); changed = true;
settings.save();
}
}, plugin); }, plugin);
function abortNoStorage() { function updateSingleDirectoryChain(isExpand, node) {
if (!c9.has(c9.STORAGE)) if (!node.children || node.children.length !== 1)
return false; return;
var child = node.children[0];
if (!child || !child.isFolder || child.$depth > 0xff)
return;
if (isExpand && !child.isOpen) {
expandNode(child);
return true;
}
else if (!isExpand && child.isOpen) {
updateSingleDirectoryChain(false, child);
delete expandedList[child.path];
return true;
}
} }
// Rename // Rename
@ -479,34 +492,58 @@ define(function(require, exports, module) {
} }
var node = e.node; var node = e.node;
var name = e.value; var name = e.value.trim();
// check for a path with the same name, which is not allowed to rename to: // check for a path with the same name, which is not allowed to rename to:
var path = node.path; var path = node.path;
var newpath = path.replace(/[^\/]+$/, name); var newpath = join(path, "..", name);
// No point in renaming when the name is the same // No point in renaming when the name is the same
if (basename(path) == name) if (path == newpath)
return; return;
// Returning false from this function will cancel the rename. We do this var m = /([\0\\\n\r])/.exec(name) || c9.platform == "win32" && /([\\:*?"<>|])/.exec(name);
// when the name to which the file is to be renamed contains invalid if (m) {
// characters
if (/[\\\/\n\r]/.test(name)) {
// todo is this still needed?
showError( showError(
"Could not rename to '" + ui.htmlentities(name) "Invalid character '" + m[0] + "' in '" + name + "'"
+ "'. Names can only contain alfanumeric characters, space, . (dot)"
+ ", - and _ (underscore). Use the terminal to rename to other names."
); );
return false; return false;
} }
fs.rename(path, newpath, {}, function(err, success) { }); // renaming to hidden file can be confusing if one doesn't know about hidden files
if (fsCache.isFileHidden(newpath) && !settings.getBool("user/projecttree/@showhidden")) {
settings.set("user/projecttree/@showhidden", true);
changed = true;
fsCache.showHidden = true;
refresh(true, function(){});
}
emit("rename", { path: newpath, oldpath: path }); if (dirname(newpath) != dirname(path)) {
tree.edit.ace.blur(); // TODO this shouldn't be needed when apf focus works
question(
"Confirm move to a new folder",
"move '" + e.oldValue + "' to \n" +
"'" + dirname(newpath) + "'?",
"",
doRename
);
} else {
doRename();
}
return false; function doRename() {
fs.rename(path, newpath, {}, function(err, success) {
if (err) {
var message = err.message;
if (err.code == "EEXIST")
message = "File " + path + " already exists.";
return showError(message);
}
if (dirname(newpath) != dirname(path))
expandAndSelect(newpath);
});
emit("rename", { path: newpath, oldpath: path });
}
}, plugin); }, plugin);
// Context Menu // Context Menu
@ -977,7 +1014,7 @@ define(function(require, exports, module) {
} }
else { else {
var node = fsCache.findNode(path); var node = fsCache.findNode(path);
if (node) //Otherwise orphan-append will pick it up if (node) // Otherwise orphan-append will pick it up
expandNode(node); expandNode(node);
} }
@ -1045,14 +1082,14 @@ define(function(require, exports, module) {
if (typeof node == "string") if (typeof node == "string")
node = fsCache.findNode(node, "refresh"); node = fsCache.findNode(node, "refresh");
if (node && !node.isFolder)
node = node.parent;
if (node && node.status === "loaded") { if (node && node.status === "loaded") {
tree.provider.setAttribute(node, "status", "pending"); tree.provider.setAttribute(node, "status", "pending");
node.children = null; node.children = null;
} }
}); });
//c9.dispatchEvent("track_action", { type: "reloadtree" });
loadProjectTree(false, function(err) { loadProjectTree(false, function(err) {
var expandedNodes = Object.keys(expandedList); var expandedNodes = Object.keys(expandedList);
expandedList = {}; expandedList = {};
@ -1067,7 +1104,7 @@ define(function(require, exports, module) {
callback(err); callback(err);
tree.provider.on("changeScrollTop", scrollHandler); tree.provider.on("changeScrollTop", scrollHandler);
emit("refreshComplete") emit("refreshComplete");
}); });
} }
@ -1100,6 +1137,7 @@ define(function(require, exports, module) {
function expandAndSelect(path_or_node) { function expandAndSelect(path_or_node) {
var node = findNode(path_or_node); var node = findNode(path_or_node);
expand(node, function(){ expand(node, function(){
refreshing = false;
tree.select(node); tree.select(node);
scrollToSelection(); scrollToSelection();
}); });
@ -1212,10 +1250,12 @@ define(function(require, exports, module) {
} }
function select(path_or_node) { function select(path_or_node) {
refreshing = false;
tree.select(findNode(path_or_node)); tree.select(findNode(path_or_node));
} }
function selectList(list) { function selectList(list) {
refreshing = false;
tree.selection.setSelection(list.map(function(n) { tree.selection.setSelection(list.map(function(n) {
return findNode(n); return findNode(n);
})); }));
@ -1293,6 +1333,9 @@ define(function(require, exports, module) {
callback(err, data); callback(err, data);
}); });
var node = fsCache.findNode(newpath, "expand");
if (node)
expandAndSelect(node);
}); });
} }

Wyświetl plik

@ -947,8 +947,10 @@ define(function(require, exports, module) {
} }
function show(x, y, type) { function show(x, y, type) {
if (type == "context") if (type == "context") {
y++; x += 2;
y += 2;
}
lastCoords = { x : x, y : y }; lastCoords = { x : x, y : y };
aml.display(x, y); aml.display(x, y);
} }