diff --git a/browser/src/App.ts b/browser/src/App.ts index 9d850ae979..336e137b8b 100644 --- a/browser/src/App.ts +++ b/browser/src/App.ts @@ -262,7 +262,13 @@ export const start = async (args: string[]): Promise => { Sidebar.activate(configuration, workspace) const sidebarManager = Sidebar.getInstance() - Explorer.activate(commandManager, editorManager, Sidebar.getInstance(), workspace) + Explorer.activate( + commandManager, + configuration, + editorManager, + Sidebar.getInstance(), + workspace, + ) Search.activate(commandManager, editorManager, Sidebar.getInstance(), workspace) Learning.activate( commandManager, diff --git a/browser/src/Input/KeyBindings.ts b/browser/src/Input/KeyBindings.ts index accdc455b9..fc8126621f 100644 --- a/browser/src/Input/KeyBindings.ts +++ b/browser/src/Input/KeyBindings.ts @@ -144,6 +144,7 @@ export const applyDefaultKeyBindings = (oni: Oni.Plugin.Api, config: Configurati input.bind("r", "explorer.rename", isExplorerActive) input.bind("", "explorer.create.file", isExplorerActive) input.bind("", "explorer.create.folder", isExplorerActive) + input.bind("", "explorer.refresh", isExplorerActive) // Browser input.bind("k", "browser.scrollUp") diff --git a/browser/src/Services/Explorer/ExplorerSplit.tsx b/browser/src/Services/Explorer/ExplorerSplit.tsx index b42a7e170f..126e11f088 100644 --- a/browser/src/Services/Explorer/ExplorerSplit.tsx +++ b/browser/src/Services/Explorer/ExplorerSplit.tsx @@ -12,6 +12,7 @@ import { FileSystemWatcher } from "./../../Services/FileSystemWatcher" import { Event } from "oni-types" import { CallbackCommand, CommandManager } from "./../../Services/CommandManager" +import { Configuration } from "./../../Services/Configuration" import { EditorManager } from "./../../Services/EditorManager" import { getInstance as NotificationsInstance } from "./../../Services/Notifications" import { windowManager } from "./../../Services/WindowManager" @@ -27,8 +28,8 @@ type Node = ExplorerSelectors.ExplorerNode export class ExplorerSplit { private _onEnterEvent: Event = new Event() private _selectedId: string = null - private _store: Store + private _watcher: FileSystemWatcher = null public get id(): string { return "oni.sidebar.explorer" @@ -39,17 +40,14 @@ export class ExplorerSplit { } constructor( - // private _configuration: Configuration, + private _configuration: Configuration, private _workspace: IWorkspace, private _commandManager: CommandManager, private _editorManager: EditorManager, ) { this._store = createStore({ notifications: NotificationsInstance() }) - const Watcher = new FileSystemWatcher({ - target: this._workspace.activeWorkspace, - options: { ignoreInitial: true, ignored: "**/node_modules" }, - }) + this._initializeFileSystemWatcher() this._workspace.onDirectoryChanged.subscribe(newDirectory => { this._store.dispatch({ @@ -57,8 +55,10 @@ export class ExplorerSplit { rootPath: newDirectory, }) - Watcher.unwatch(this._workspace.activeWorkspace) - Watcher.watch(newDirectory) + if (this._watcher) { + this._watcher.unwatch(this._workspace.activeWorkspace) + this._watcher.watch(newDirectory) + } }) if (this._workspace.activeWorkspace) { @@ -67,11 +67,6 @@ export class ExplorerSplit { rootPath: this._workspace.activeWorkspace, }) } - - const events = ["onChange", "onAdd", "onAddDir", "onMove", "onDelete", "onDeleteDir"] - events.forEach(event => - Watcher[event].subscribe(() => this._store.dispatch({ type: "REFRESH" })), - ) } public enter(): void { @@ -104,11 +99,27 @@ export class ExplorerSplit { ) } + private _initializeFileSystemWatcher(): void { + if (this._configuration.getValue("explorer.autoRefresh")) { + this._watcher = new FileSystemWatcher({ + target: this._workspace.activeWorkspace, + options: { ignoreInitial: true, ignored: "**/node_modules" }, + }) + + const events = ["onChange", "onAdd", "onAddDir", "onMove", "onDelete", "onDeleteDir"] + events.forEach(event => this._watcher[event].subscribe(() => this._refresh())) + } + } + private _inputInProgress = () => { const { register: { rename, create } } = this._store.getState() return rename.active || create.active } + private _refresh(): void { + this._store.dispatch({ type: "REFRESH" }) + } + private _initialiseExplorerCommands(): void { this._commandManager.registerCommand( new CallbackCommand( @@ -153,6 +164,15 @@ export class ExplorerSplit { ), ) + this._commandManager.registerCommand( + new CallbackCommand( + "explorer.refresh", + "Explorer: Refresh the tree", + "Updates the explorer with the latest state on the file system", + () => !this._inputInProgress() && this._refresh(), + ), + ) + this._commandManager.registerCommand( new CallbackCommand( "explorer.create.file", diff --git a/browser/src/Services/Explorer/index.tsx b/browser/src/Services/Explorer/index.tsx index 022aefe55e..5add265a9e 100644 --- a/browser/src/Services/Explorer/index.tsx +++ b/browser/src/Services/Explorer/index.tsx @@ -5,6 +5,7 @@ */ import { CommandManager } from "./../CommandManager" +import { Configuration } from "./../Configuration" import { EditorManager } from "./../EditorManager" import { SidebarManager } from "./../Sidebar" import { Workspace } from "./../Workspace" @@ -13,9 +14,20 @@ import { ExplorerSplit } from "./ExplorerSplit" export const activate = ( commandManager: CommandManager, + configuration: Configuration, editorManager: EditorManager, sidebarManager: SidebarManager, workspace: Workspace, ) => { - sidebarManager.add("files-o", new ExplorerSplit(workspace, commandManager, editorManager)) + configuration.registerSetting("explorer.autoRefresh", { + description: + "When set to true, the explorer will listen for changes on the file system and refresh automatically.", + requiresReload: true, + defaultValue: false, + }) + + sidebarManager.add( + "files-o", + new ExplorerSplit(configuration, workspace, commandManager, editorManager), + ) }