From ca11663e120b89dc021aa166f2ce15b3fe01bc58 Mon Sep 17 00:00:00 2001 From: Bhakta Raghavan Date: Thu, 10 Dec 2020 16:49:41 +0530 Subject: [PATCH] Recent-Folders: Track most recent files When working with large remote repositories, its becomes hard to navigate back to files that were previously opened and close (especially if the repo has large tree structure with nested folders). Recent-Folders will locally track the set of open files. When a file is opened, it will be added in Recent-Files. If the file window is closed, it can be opened back from Recent-Files. Recent-Files is an option that is disabled by default in the main config. --- lib/config/config-schema.json | 7 ++++ lib/views/directory-view.js | 73 ++++++++++++++++++++++++++--------- lib/views/file-view.js | 23 +++++++++++ lib/views/folder-view.js | 13 ++++++- lib/views/server-view.js | 48 +++++++++++++++++++++++ lib/views/tree-view.js | 5 +++ 6 files changed, 150 insertions(+), 19 deletions(-) diff --git a/lib/config/config-schema.json b/lib/config/config-schema.json index 01ebd08..f416a0f 100755 --- a/lib/config/config-schema.json +++ b/lib/config/config-schema.json @@ -79,6 +79,13 @@ "type": "boolean", "default": true, "order": 9 + }, + "showRecentFiles": { + "title": "Show Recent files", + "description": "For every remote server, show list of recent accessed file(s)", + "type": "boolean", + "default": false, + "order": 10 } }, "order": 3 diff --git a/lib/views/directory-view.js b/lib/views/directory-view.js index 0667142..7bf7f77 100755 --- a/lib/views/directory-view.js +++ b/lib/views/directory-view.js @@ -27,6 +27,7 @@ class DirectoryView extends View { self.name = null; self.rights = null; self.isExpanded = false; + self.internalCache = false; } static content() { @@ -68,6 +69,7 @@ class DirectoryView extends View { self.config = parent.config; self.name = directory.name; self.rights = directory.rights; + self.internalCache = directory.internalCache ? directory.internalCache : false; self.isExpanded = false; self.id = self.getId(); @@ -157,6 +159,16 @@ class DirectoryView extends View { return element; } + addRecentFileEntry(file) { + const self = this; + self.parent.addRecentFileEntry(file) + } + + delRecentFileEntry(file) { + const self = this; + self.parent.delRecentFileEntry(file) + } + paint(list) { const self = this; let entries = []; @@ -191,7 +203,6 @@ class DirectoryView extends View { directories.forEach(function (element) { let pathOnFileSystem = self.getPath() + element.name; pathOnFileSystem = pathOnFileSystem.replace(/\/+/g, "/"); - if (!isPathIgnored(pathOnFileSystem)) { let li = new DirectoryView(self, { name: element.name, @@ -228,9 +239,21 @@ class DirectoryView extends View { }); } + if (self.showRecentFilesCache) { + const pathOnFileSystem = self.getPath() + "__FTP_REMOTE_EDIT_PLUS_RECENT_FILES__"; + self.cacheFolderDirectoryView = new DirectoryView(self, { + name: "Recent-Files", + path: pathOnFileSystem, + rights: {user: "rwx", group: "rx", others: "rx"}, + internalCache: true, + }); + entries.unshift(self.cacheFolderDirectoryView); + } + entries.forEach(function (entry) { self.entries.append(entry); }); + }; setClasses() { @@ -259,24 +282,38 @@ class DirectoryView extends View { self.deselect(); self.select(self); - self.getRoot() - .connector.listDirectory(self.getPath()) - .then((list) => { - self.paint(list); - self.label.removeClass('icon-sync') - .removeClass('spin') - .addClass('icon-file-directory'); - resolve(true); - }) - .catch(function (err) { - self.getRoot() - .connector.showMessage(err.message, 'error'); - self.label.removeClass('icon-sync') - .removeClass('spin') - .addClass('icon-file-directory'); - self.collapse(); - reject(err); + if (!self.internalCache) { + self.getRoot() + .connector.listDirectory(self.getPath()) + .then((list) => { + self.paint(list); + self.label.removeClass('icon-sync') + .removeClass('spin') + .addClass('icon-file-directory'); + resolve(true); + }) + .catch(function (err) { + self.getRoot() + .connector.showMessage(err.message, 'error'); + self.label.removeClass('icon-sync') + .removeClass('spin') + .addClass('icon-file-directory'); + self.collapse(); + reject(err); + }); + } else { + + let entries = self.parent.getRecentFileEntries(); + self.entries.children().detach(); + entries.forEach((entry) => { + self.entries.append(entry); }); + // self.paint(list); + self.label.removeClass('icon-sync') + .removeClass('spin') + .addClass('icon-file-directory'); + resolve(true); + } }); return promise; diff --git a/lib/views/file-view.js b/lib/views/file-view.js index 941a2e9..37f89eb 100755 --- a/lib/views/file-view.js +++ b/lib/views/file-view.js @@ -60,6 +60,7 @@ class FileView extends View { self.size = file.size; self.rights = file.rights; self.id = self.getId(); + self.internalCache = file.internalCache ? file.internalCache : false; // Add filename self.label.text(self.name); @@ -191,6 +192,22 @@ class FileView extends View { element.label.removeClass('icon-sync').removeClass('spin'); }; + addRecentFileEntry(file) { + const self = this; + const showRecentFiles = atom.config.get('ftp-remote-edit-plus.tree.showRecentFiles') + if (showRecentFiles) { + // Create a clone object and add it + const fileObjectClone = new FileView(file.parent, { + name: file.name, + path: "", + size: file.size, + rights: file.rights, + internalCache: true + }); + self.parent.addRecentFileEntry(fileObjectClone); + } + } + open(pending = false) { const self = this; @@ -199,6 +216,7 @@ class FileView extends View { // Check if file is already opened in texteditor if (self.getTextEditor(self.getLocalPath(true) + self.name, true)) { atom.workspace.open(self.getLocalPath(true) + self.name, { pending: pending, searchAllPanes: true }) + self.addRecentFileEntry(self); return false; } @@ -231,6 +249,7 @@ class FileView extends View { // Open file in texteditor return atom.workspace.open(self.getLocalPath(true) + self.name, { pending: pending, searchAllPanes: true }) .then((editor) => { + self.addRecentFileEntry(self); if (self.editor === null || self.editor === undefined) { self.editor = editor; editor.saveObject = self; @@ -437,6 +456,10 @@ class FileView extends View { deleteFile() { const self = this; + if (self.internalCache) { + // Internal cache file.. skip delete + return; + } self.getRoot() .connector.deleteFile(self.getPath(true) + self.name) .then(() => { diff --git a/lib/views/folder-view.js b/lib/views/folder-view.js index 2f49685..868de2d 100755 --- a/lib/views/folder-view.js +++ b/lib/views/folder-view.js @@ -19,6 +19,7 @@ class FolderView extends DirectoryView { self.servers = []; self.isExpanded = false; self.debug = false; + self.showRecentFilesCache = false; } static content() { @@ -67,6 +68,7 @@ class FolderView extends DirectoryView { self.debug = false; } + self.label.text(self.name); self.label.addClass('icon-file-symlink-directory'); self.addClass('project-root'); @@ -119,7 +121,6 @@ class FolderView extends DirectoryView { expand() { const self = this; - let promise = new Promise((resolve, reject) => { self.entries.children() .detach(); @@ -172,6 +173,16 @@ class FolderView extends DirectoryView { .addClass('icon-file-directory'); }; + addRecentFileEntry(file) { + const self = this; + self.parent.addRecentFileEntry(file) + } + + delRecentFileEntry(file) { + const self = this; + self.parent.delRecentFileEntry(file) + } + onDragStart(e) { const self = this; let entry, initialPath; diff --git a/lib/views/server-view.js b/lib/views/server-view.js index b494431..d12b66d 100755 --- a/lib/views/server-view.js +++ b/lib/views/server-view.js @@ -20,6 +20,10 @@ class ServerView extends DirectoryView { self.isExpanded = false; self.debug = false; self.finderItemsCache = null; + self.recentFilesCache = []; + self.showRecentFilesCache = false; + self.cacheFolderDirectoryView = null; + self.recentFilesCacheFolderEntry = {} } static content() { @@ -78,6 +82,23 @@ class ServerView extends DirectoryView { self.connector = null; self.connector = new Connector(self.config); + self.recentFilesCache = []; + self.showRecentFilesCache = atom.config.get('ftp-remote-edit-plus.tree.showRecentFiles'); + if (self.showRecentFilesCache) { + self.recentFilesCacheFolderEntry = { + accessTime: new Date().getTime(), + group: 0, + modifyTime: new Date().getTime(), + owner: 0, + permission: "755", + rights: {user: "rwx", group: "rwx", others: "rwx"}, + size: 0, + type: "d", + internalCache: true + }; + } + + // Events self.connector.on('log', function (msg) { self.treeView.ftpLogView.trigger('log', msg); @@ -120,6 +141,33 @@ class ServerView extends DirectoryView { return 'ftp-remote-edit-' + md5(JSON.stringify(object)); } + addRecentFileEntry(file) { + const self = this; + const res = self.recentFilesCache.filter(item => item.id === file.id); + if (res.length === 0) { + self.recentFilesCache.unshift(file); + } + + if (self.cacheFolderDirectoryView) { + if (self.cacheFolderDirectoryView.isExpanded) { + self.cacheFolderDirectoryView.expand(); + } + } + } + + delRecentFileEntry(file) { + const self = this; + const res = self.recentFilesCache.filter(item => item.id === file.id); + if (res.length !== 0) { + self.recentFilesCache = self.recentFilesCache.filter(item => item.id != file.id); + } + } + + getRecentFileEntries() { + const self = this; + return self.recentFilesCache; + } + collapse() { const self = this; diff --git a/lib/views/tree-view.js b/lib/views/tree-view.js index d2549f8..c49ac84 100755 --- a/lib/views/tree-view.js +++ b/lib/views/tree-view.js @@ -116,6 +116,11 @@ class TreeView extends ScrollView { self.reload(); } }); + atom.config.onDidChange('ftp-remote-edit.tree.showRecentFiles', () => { + if (self.isVisible()) { + self.reload(); + } + }); atom.config.onDidChange('ftp-remote-edit.tree.hideIgnoredNames', () => { resetIgnoredPatterns(); if (self.isVisible()) {