This repository has been archived by the owner on Apr 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add session manager, store and sidebar pane * hook up session services to app * move side effects into epics * add creation and cancel creation actions * add restore session epic and remove console.log * await sessions in case of error * add error handling to session functions * Revert "Refocus previously open menu on reactivating Oni (#2472)" This reverts commit 97f0c61. * Revert "Refocus previously open menu on reactivating Oni (#2472)" This reverts commit 97f0c61. * remove console.log * remove unused props passed to session pane * add persist session command [WIP] * Add current session action and update store with i t * use get user config add icons and some error handling * add unclick handlers for sessions move section title to general location add delete session functionality * add title and toggling of sessions add on vim leave handler * fix lint errors * refactor epics in preparation for 1.0 and rxjs 6 * update snapshot * add bufdo bd command prior to restoring session fix delete session bug causing reappearances * create separate close all buffers method * remove update session method * Add audit time to update current session * add close all buffers method and use persist session action in update session * add restore session error action and complete action * add console log for debugging return metadata directly * add error handling to git blame function * reduce persist audit time make ids in session.tsx readonly * comment out console.log * check neovim for current session when updating this ensures the session is valid added getCurrentSession method which checks vims v:this_session var * fix lint errors * add tests for sessions component and mock for neovim instance * switch generic input check to specific text input view check * add update timestamp functionality so these are more accurate * switch to adding updated at by checking mtime of f ile * switch to storing sessions in persistent store * add delete functionality to persistent store and mock * fix lint error * rename sessionName var to name for simplicity * add session manager initial test * create path using path.join * add experimental config flag * update Oni mock and increase sessionmanager tests * add session store tests - [WIP] * return simple session manager mock remove need for instantiation, use done callback * remove session store tests as redux observable api has changed a large refactor of all observables is going to be required to upgrade redux observable so seems counter productive to write tests that will need to be re-written entirely once that is done * add user configurable session directory * tweak sidebar item styles * update vim navigator to pass function to update selected item on click render session sidebar item second * fix lint error * fix broken tests
- Loading branch information
Showing
37 changed files
with
1,245 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import * as fs from "fs-extra" | ||
import { Editor, EditorManager, Plugin } from "oni-api" | ||
import { IEvent } from "oni-types" | ||
import * as path from "path" | ||
|
||
import { SidebarManager } from "../Sidebar" | ||
import { SessionActions, SessionsPane, store } from "./" | ||
import { getPersistentStore, IPersistentStore } from "./../../PersistentStore" | ||
import { getUserConfigFolderPath } from "./../../Services/Configuration/UserConfiguration" | ||
|
||
export interface ISession { | ||
name: string | ||
id: string | ||
file: string | ||
directory: string | ||
updatedAt?: string | ||
workspace: string | ||
// can be use to save other metadata for restoration like statusbar info or sidebar info etc | ||
metadata?: { [key: string]: any } | ||
} | ||
|
||
export interface ISessionService { | ||
sessionsDir: string | ||
sessions: ISession[] | ||
persistSession(sessionName: string): Promise<ISession> | ||
restoreSession(sessionName: string): Promise<ISession> | ||
} | ||
|
||
export interface UpdatedOni extends Plugin.Api { | ||
editors: UpdatedEditorManager | ||
} | ||
|
||
interface UpdatedEditorManager extends EditorManager { | ||
activeEditor: UpdatedEditor | ||
} | ||
|
||
interface UpdatedEditor extends Editor { | ||
onQuit: IEvent<void> | ||
persistSession(sessionDetails: ISession): Promise<ISession> | ||
restoreSession(sessionDetails: ISession): Promise<ISession> | ||
getCurrentSession(): Promise<string | void> | ||
} | ||
|
||
/** | ||
* Class SessionManager | ||
* | ||
* Provides a service to manage oni session i.e. buffers, screen layout etc. | ||
* | ||
*/ | ||
export class SessionManager implements ISessionService { | ||
private _store = store({ sessionManager: this, fs }) | ||
private get _sessionsDir() { | ||
const defaultDirectory = path.join(getUserConfigFolderPath(), "sessions") | ||
const userDirectory = this._oni.configuration.getValue<string>( | ||
"experimental.sessions.directory", | ||
) | ||
const directory = userDirectory || defaultDirectory | ||
return directory | ||
} | ||
|
||
constructor( | ||
private _oni: UpdatedOni, | ||
private _sidebarManager: SidebarManager, | ||
private _persistentStore: IPersistentStore<{ [sessionName: string]: ISession }>, | ||
) { | ||
fs.ensureDirSync(this.sessionsDir) | ||
const enabled = this._oni.configuration.getValue<boolean>("experimental.sessions.enabled") | ||
if (enabled) { | ||
this._sidebarManager.add( | ||
"save", | ||
new SessionsPane({ store: this._store, commands: this._oni.commands }), | ||
) | ||
} | ||
this._setupSubscriptions() | ||
} | ||
|
||
public get sessions() { | ||
return this._store.getState().sessions | ||
} | ||
|
||
public get sessionsDir() { | ||
return this._sessionsDir | ||
} | ||
|
||
public async updateOniSession(name: string, value: Partial<ISession>) { | ||
const persistedSessions = await this._persistentStore.get() | ||
if (name in persistedSessions) { | ||
this._persistentStore.set({ | ||
...persistedSessions, | ||
[name]: { ...persistedSessions[name], ...value }, | ||
}) | ||
} | ||
} | ||
|
||
public async createOniSession(sessionName: string) { | ||
const persistedSessions = await this._persistentStore.get() | ||
const file = this._getSessionFilename(sessionName) | ||
|
||
const session: ISession = { | ||
file, | ||
id: sessionName, | ||
name: sessionName, | ||
directory: this.sessionsDir, | ||
workspace: this._oni.workspace.activeWorkspace, | ||
metadata: null, | ||
} | ||
|
||
this._persistentStore.set({ ...persistedSessions, [sessionName]: session }) | ||
|
||
return session | ||
} | ||
|
||
/** | ||
* Retrieve or Create a persistent Oni Session | ||
* | ||
* @name getSessionFromStore | ||
* @function | ||
* @param {string} sessionName The name of the session | ||
* @returns {ISession} The session metadata object | ||
*/ | ||
public async getSessionFromStore(name: string) { | ||
const sessions = await this._persistentStore.get() | ||
if (name in sessions) { | ||
return sessions[name] | ||
} | ||
return this.createOniSession(name) | ||
} | ||
|
||
public persistSession = async (sessionName: string) => { | ||
const sessionDetails = await this.getSessionFromStore(sessionName) | ||
await this._oni.editors.activeEditor.persistSession(sessionDetails) | ||
return sessionDetails | ||
} | ||
|
||
public deleteSession = async (sessionName: string) => { | ||
await this._persistentStore.delete(sessionName) | ||
} | ||
|
||
public getCurrentSession = async () => { | ||
const filepath = await this._oni.editors.activeEditor.getCurrentSession() | ||
if (!filepath) { | ||
return null | ||
} | ||
const [name] = path.basename(filepath).split(".") | ||
return filepath.includes(this._sessionsDir) ? this.getSessionFromStore(name) : null | ||
} | ||
|
||
public restoreSession = async (name: string) => { | ||
const sessionDetails = await this.getSessionFromStore(name) | ||
await this._oni.editors.activeEditor.restoreSession(sessionDetails) | ||
const session = await this.getCurrentSession() | ||
return session | ||
} | ||
|
||
private _getSessionFilename(name: string) { | ||
return path.join(this.sessionsDir, `${name}.vim`) | ||
} | ||
|
||
private _setupSubscriptions() { | ||
this._oni.editors.activeEditor.onBufferEnter.subscribe(() => { | ||
this._store.dispatch(SessionActions.updateCurrentSession()) | ||
}) | ||
this._oni.editors.activeEditor.onQuit.subscribe(() => { | ||
this._store.dispatch(SessionActions.updateCurrentSession()) | ||
}) | ||
} | ||
} | ||
|
||
function init() { | ||
let instance: SessionManager | ||
return { | ||
getInstance: () => instance, | ||
activate: (oni: Plugin.Api, sidebarManager: SidebarManager) => { | ||
const persistentStore = getPersistentStore("sessions", {}, 1) | ||
instance = new SessionManager(oni as UpdatedOni, sidebarManager, persistentStore) | ||
}, | ||
} | ||
} | ||
export const { activate, getInstance } = init() |
Oops, something went wrong.