diff options
Diffstat (limited to 'modules/ext')
| -rw-r--r-- | modules/ext/course.js | 5 | ||||
| -rw-r--r-- | modules/ext/critical-ext-bundle.js | 13 | ||||
| -rw-r--r-- | modules/ext/filemgr.js | 13 |
3 files changed, 22 insertions, 9 deletions
diff --git a/modules/ext/course.js b/modules/ext/course.js index d3b96de..8c615ec 100644 --- a/modules/ext/course.js +++ b/modules/ext/course.js @@ -177,7 +177,10 @@ class CourseModule { if (cmd === 'course') return; // Only capture while an exercise is actually running. Capturing every command // swallowed all terminal output (pwd/help/version printed nothing). - if (!this._active || !this._active.lesson || !this._active.lesson.exercise) return; + if (!this._active || !this._active.lesson || !this._active.lesson.exercise) { + this._capOut = ''; // never let a previous command's output satisfy an output-check exercise + return; + } if (this._capActive) { try { this.terminal._popPrintCapture(); } catch (e) {} if (this._capOut) { try { this.terminal.print(this._capOut.replace(/\n+$/, '')); } catch (e) {} } diff --git a/modules/ext/critical-ext-bundle.js b/modules/ext/critical-ext-bundle.js index 504dfa8..8f63081 100644 --- a/modules/ext/critical-ext-bundle.js +++ b/modules/ext/critical-ext-bundle.js @@ -1737,6 +1737,10 @@ class FileManagerModule { const name = src.split('/').pop(); const destPath = dest === '/' ? '/' + name : dest + '/' + name; if (destPath === src || destPath.startsWith(src + '/')) { skipped++; return; } + // Directory → existing directory would REPLACE the whole subtree silently; skip it. + let srcIsDir = false; + try { srcIsDir = typeof fs.readDir === 'function' && fs.readDir(src) !== null; } catch (_e) {} + if (this._exists(destPath) && srcIsDir) { skipped++; return; } if (this._exists(destPath) && !confirm('Overwrite ' + destPath + '?')) { skipped++; return; } try { const ok = this._clipboard.mode === 'copy' ? fs.copy(src, destPath) : fs.move(src, destPath); @@ -1754,8 +1758,8 @@ class FileManagerModule { _batchDelete() { const paths = this._getSelectedPaths(); - if (!paths.length) { this._updateStatus('No files selected'); return; } - if (!confirm('Delete ' + paths.length + ' item(s)?')) return; + if (!paths.length) { this._updateStatus('No files selected'); return false; } + if (!confirm('Delete ' + paths.length + ' item(s)?')) return false; const fs = this.terminal.fs; let count = 0, failed = 0; paths.forEach(p => { @@ -1768,6 +1772,7 @@ class FileManagerModule { this._selectedFile = null; this._refreshFileList(); this._updateStatus('🗑️ Deleted ' + count + ' item(s)' + (failed ? ' — ' + failed + ' failed' : '')); + return count > 0; } _batchRename() { @@ -1880,8 +1885,8 @@ class FileManagerModule { if (!this._getSelectedPaths().length && this._selectedFile) { this._multiSelect.add(this._selectedFile); } - this._batchDelete(); - this._clearPreview(); + // Only clear the preview when something was actually deleted (not on cancel). + if (this._batchDelete()) this._clearPreview(); } _actionDownload() { diff --git a/modules/ext/filemgr.js b/modules/ext/filemgr.js index 28c62ce..e099a34 100644 --- a/modules/ext/filemgr.js +++ b/modules/ext/filemgr.js @@ -804,6 +804,10 @@ class FileManagerModule { const name = src.split('/').pop(); const destPath = dest === '/' ? '/' + name : dest + '/' + name; if (destPath === src || destPath.startsWith(src + '/')) { skipped++; return; } + // Directory → existing directory would REPLACE the whole subtree silently; skip it. + let srcIsDir = false; + try { srcIsDir = typeof fs.readDir === 'function' && fs.readDir(src) !== null; } catch (_e) {} + if (this._exists(destPath) && srcIsDir) { skipped++; return; } if (this._exists(destPath) && !confirm('Overwrite ' + destPath + '?')) { skipped++; return; } try { const ok = this._clipboard.mode === 'copy' ? fs.copy(src, destPath) : fs.move(src, destPath); @@ -821,8 +825,8 @@ class FileManagerModule { _batchDelete() { const paths = this._getSelectedPaths(); - if (!paths.length) { this._updateStatus('No files selected'); return; } - if (!confirm('Delete ' + paths.length + ' item(s)?')) return; + if (!paths.length) { this._updateStatus('No files selected'); return false; } + if (!confirm('Delete ' + paths.length + ' item(s)?')) return false; const fs = this.terminal.fs; let count = 0, failed = 0; paths.forEach(p => { @@ -835,6 +839,7 @@ class FileManagerModule { this._selectedFile = null; this._refreshFileList(); this._updateStatus('🗑️ Deleted ' + count + ' item(s)' + (failed ? ' — ' + failed + ' failed' : '')); + return count > 0; } _batchRename() { @@ -947,8 +952,8 @@ class FileManagerModule { if (!this._getSelectedPaths().length && this._selectedFile) { this._multiSelect.add(this._selectedFile); } - this._batchDelete(); - this._clearPreview(); + // Only clear the preview when something was actually deleted (not on cancel). + if (this._batchDelete()) this._clearPreview(); } _actionDownload() { |