From 79ee9a9f6851a0a285e9aaad3dfbccb95905bb50 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 08:43:06 -0400 Subject: [PATCH 1/7] fix: add history settings --- src/constants.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/constants.ts b/src/constants.ts index 1e31eed..ca31e9a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -25,6 +25,8 @@ export const DEFAULT_PROFILES: Record = } } export const DEFAULT_FOLDER = '$CWD' +export const DEFAULT_HISTORY_ENABLED = true +export const DEFAULT_HISTORY_SAVE_RESULT = true export const DEFAULT_SETTING_RUNNER_SHORTCUT = '`+CommandOrControl' export const DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT = '`+Shift+CommandOrControl' export const DEFAULT_SETTING_IS_COMMANDER_MODE = true @@ -46,6 +48,10 @@ export const DEFAULT_SETTING_RUNNER_BOUNDS = { export const DEFAULT_SETTINGS = { defaultProfile: DEFAULT_PROFILE, profiles: DEFAULT_PROFILES, + history: { + enabled: DEFAULT_HISTORY_ENABLED, + saveResult: DEFAULT_HISTORY_SAVE_RESULT + }, runner: { shortcut: DEFAULT_SETTING_RUNNER_SHORTCUT, bounds: DEFAULT_SETTING_RUNNER_BOUNDS, From 2fd3cdf4ad4706e2751201582628af24396fd561 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 09:01:18 -0400 Subject: [PATCH 2/7] fix: history model --- src/constants.ts | 4 +++ src/main/framework/history.ts | 48 +++++++++++++++++++++++++++++++++ src/main/framework/workspace.ts | 3 +++ 3 files changed, 55 insertions(+) create mode 100644 src/main/framework/history.ts diff --git a/src/constants.ts b/src/constants.ts index ca31e9a..62c6372 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -26,6 +26,8 @@ export const DEFAULT_PROFILES: Record = } export const DEFAULT_FOLDER = '$CWD' export const DEFAULT_HISTORY_ENABLED = true + +export const DEFAULT_HISTORY_MAX_ITEMS = 100 export const DEFAULT_HISTORY_SAVE_RESULT = true export const DEFAULT_SETTING_RUNNER_SHORTCUT = '`+CommandOrControl' export const DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT = '`+Shift+CommandOrControl' @@ -45,11 +47,13 @@ export const DEFAULT_SETTING_RUNNER_BOUNDS = { w: 720, h: 500 } + export const DEFAULT_SETTINGS = { defaultProfile: DEFAULT_PROFILE, profiles: DEFAULT_PROFILES, history: { enabled: DEFAULT_HISTORY_ENABLED, + maxItems: DEFAULT_HISTORY_MAX_ITEMS, saveResult: DEFAULT_HISTORY_SAVE_RESULT }, runner: { diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts new file mode 100644 index 0000000..bd99e2c --- /dev/null +++ b/src/main/framework/history.ts @@ -0,0 +1,48 @@ +import { pathExists, readJSON, writeFile, writeJson } from 'fs-extra' +import { Command } from './runtime' + +export interface HistoricalExecution { + prompt: string + result?: string + error: boolean + aborted: boolean + profile: string + when: number + code: number +} + +export class History { + public execution: HistoricalExecution[] = [] + + constructor(public location: string) {} + + async load(): Promise { + const isExist = await pathExists(this.location) + if (!isExist) { + const prettyJSON = JSON.stringify([], null, 2) + + await writeFile(this.location, prettyJSON, 'utf-8') + } else { + this.execution = await readJSON(this.location) + } + } + append(command: Command, profile: string, saveResult: boolean, max: number): void { + if (this.execution.length + 1 > max) { + this.execution.shift() + } + + this.execution.push({ + prompt: command.prompt, + aborted: command.aborted, + result: saveResult ? command.result.stream.map((o) => o.raw).join('\n') : undefined, + error: command.error, + profile, + when: Date.now(), + code: command.result.code + }) + } + + async write(): Promise { + await writeJson(this.location, this.execution) + } +} diff --git a/src/main/framework/workspace.ts b/src/main/framework/workspace.ts index 58b4b7e..4817f65 100644 --- a/src/main/framework/workspace.ts +++ b/src/main/framework/workspace.ts @@ -10,6 +10,7 @@ import { Runtime } from './runtime' import { DEFAULT_FOLDER } from '../../constants' import { Commands } from './commands' import { Store } from './store' +import { History } from './history' export function resolveFolderPathForMTERM(folder: string): string { folder = folder.replace('~', homedir()) @@ -21,6 +22,7 @@ export function resolveFolderPathForMTERM(folder: string): string { } export class Workspace { public store: Store + public history: History public settings: Settings public commands: Commands public isAppQuiting: boolean = false @@ -38,6 +40,7 @@ export class Workspace { this.commands = new Commands(join(this.folder), join(app.getAppPath(), './resources/commands')) this.settings = new Settings(join(this.folder, 'settings.json'), defaultSettings) + this.history = new History(join(this.folder, '.history')) this.store = new Store(join(this.folder, '.mterm-store')) } From 798ce6c09efde079bbdf55ed91315897893842d9 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 09:27:24 -0400 Subject: [PATCH 3/7] fix: persist loop in workspace and confirm all flows go through finish --- src/main/bootstrap/index.ts | 9 +++++++++ src/main/framework/history.ts | 12 +++++++++--- src/main/framework/runtime-events.ts | 27 +++++++++++++++----------- src/main/framework/runtime-executor.ts | 1 + src/main/framework/workspace.ts | 10 +++++++++- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/main/bootstrap/index.ts b/src/main/bootstrap/index.ts index 7d84cdb..1ce8690 100644 --- a/src/main/bootstrap/index.ts +++ b/src/main/bootstrap/index.ts @@ -64,7 +64,16 @@ export async function boostrap(context: BootstrapContext): Promise { } }) + await workspace.history.load() await workspace.commands.load(workspace.settings) + + setTimeout( + () => + workspace.persist().catch((error) => { + console.error(error) + }), + workspace.settings.get('workspace.persistTimeout', 5000) + ) } catch (e) { console.error(e) diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts index bd99e2c..9be2594 100644 --- a/src/main/framework/history.ts +++ b/src/main/framework/history.ts @@ -7,7 +7,10 @@ export interface HistoricalExecution { error: boolean aborted: boolean profile: string - when: number + when: { + start: number + finish: number + } code: number } @@ -26,7 +29,7 @@ export class History { this.execution = await readJSON(this.location) } } - append(command: Command, profile: string, saveResult: boolean, max: number): void { + append(command: Command, start: number, profile: string, saveResult: boolean, max: number): void { if (this.execution.length + 1 > max) { this.execution.shift() } @@ -37,7 +40,10 @@ export class History { result: saveResult ? command.result.stream.map((o) => o.raw).join('\n') : undefined, error: command.error, profile, - when: Date.now(), + when: { + start, + finish: Date.now() + }, code: command.result.code }) } diff --git a/src/main/framework/runtime-events.ts b/src/main/framework/runtime-events.ts index e1e8bb7..049ae04 100644 --- a/src/main/framework/runtime-events.ts +++ b/src/main/framework/runtime-events.ts @@ -260,6 +260,19 @@ export function attach({ app, workspace }: BootstrapContext): void { let finalize: boolean = true + const finish = (code: number): void => { + if (command.aborted || command.complete) { + return + } + + result.code = code + + command.complete = true + command.error = result.code !== 0 + + console.log('FINISH', command.prompt) + } + try { const out = (text: string, error: boolean = false): void => { if (command.aborted || command.complete) { @@ -289,16 +302,6 @@ export function attach({ app, workspace }: BootstrapContext): void { _.sender.send('runtime.commandEvent', streamEvent) } } - const finish = (code: number): void => { - if (command.aborted || command.complete) { - return - } - - result.code = code - - command.complete = true - command.error = result.code !== 0 - } if (!profile) { throw `Profile ${profileKey} does not exist, provided by runtime as = ${runtimeTarget.profile}` @@ -322,12 +325,14 @@ export function attach({ app, workspace }: BootstrapContext): void { text: `${e}`, raw: `${e}` }) - result.code = 1 + finish(1) } if (finalize) { command.complete = true command.error = result.code !== 0 + + finish(result.code) } return command diff --git a/src/main/framework/runtime-executor.ts b/src/main/framework/runtime-executor.ts index 9edf2dc..6c0ab8c 100644 --- a/src/main/framework/runtime-executor.ts +++ b/src/main/framework/runtime-executor.ts @@ -27,6 +27,7 @@ export async function execute(context: ExecuteContext): Promise if (systemCommand.command === cmd || systemCommand?.alias?.includes(cmd)) { await systemCommand.task(context, ...args) + finish(0) return } } diff --git a/src/main/framework/workspace.ts b/src/main/framework/workspace.ts index 4817f65..3a20df5 100644 --- a/src/main/framework/workspace.ts +++ b/src/main/framework/workspace.ts @@ -7,7 +7,7 @@ import { remove } from 'lodash' import { app, BrowserWindowConstructorOptions } from 'electron' import { setWindowValueFromPath } from '../util' import { Runtime } from './runtime' -import { DEFAULT_FOLDER } from '../../constants' +import { DEFAULT_FOLDER, DEFAULT_HISTORY_ENABLED } from '../../constants' import { Commands } from './commands' import { Store } from './store' import { History } from './history' @@ -162,6 +162,14 @@ export class Workspace { } } } + + async persist(): Promise { + const saveHistory = this.settings.get('history.enabled', DEFAULT_HISTORY_ENABLED) + if (saveHistory) { + await this.history.write() + } + } + /** * Applies the updated settings to all the windows in the workspace. * From 5f96c98a7556ed62d0ea9375fa094595a7a58374 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 09:39:48 -0400 Subject: [PATCH 4/7] fix: history execution save on command completion --- src/main/bootstrap/index.ts | 4 ++-- src/main/framework/history.ts | 6 +++--- src/main/framework/runtime-events.ts | 14 +++++++++++++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/bootstrap/index.ts b/src/main/bootstrap/index.ts index 1ce8690..a64556d 100644 --- a/src/main/bootstrap/index.ts +++ b/src/main/bootstrap/index.ts @@ -67,12 +67,12 @@ export async function boostrap(context: BootstrapContext): Promise { await workspace.history.load() await workspace.commands.load(workspace.settings) - setTimeout( + setInterval( () => workspace.persist().catch((error) => { console.error(error) }), - workspace.settings.get('workspace.persistTimeout', 5000) + workspace.settings.get('workspace.persistInterval', 5000) ) } catch (e) { console.error(e) diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts index 9be2594..a0072a8 100644 --- a/src/main/framework/history.ts +++ b/src/main/framework/history.ts @@ -3,7 +3,7 @@ import { Command } from './runtime' export interface HistoricalExecution { prompt: string - result?: string + result?: string[] error: boolean aborted: boolean profile: string @@ -37,7 +37,7 @@ export class History { this.execution.push({ prompt: command.prompt, aborted: command.aborted, - result: saveResult ? command.result.stream.map((o) => o.raw).join('\n') : undefined, + result: saveResult ? command.result.stream.map((o) => o.raw) : undefined, error: command.error, profile, when: { @@ -49,6 +49,6 @@ export class History { } async write(): Promise { - await writeJson(this.location, this.execution) + await writeFile(this.location, JSON.stringify(this.execution, null, 2)) } } diff --git a/src/main/framework/runtime-events.ts b/src/main/framework/runtime-events.ts index 049ae04..389d85d 100644 --- a/src/main/framework/runtime-events.ts +++ b/src/main/framework/runtime-events.ts @@ -16,6 +16,9 @@ import { execute } from './runtime-executor' import createDOMPurify from 'dompurify' import { JSDOM } from 'jsdom' import { + DEFAULT_HISTORY_ENABLED, + DEFAULT_HISTORY_MAX_ITEMS, + DEFAULT_HISTORY_SAVE_RESULT, DEFAULT_PROFILE, DEFAULT_PROFILES, DEFAULT_SETTING_IS_COMMANDER_MODE @@ -253,10 +256,17 @@ export function attach({ app, workspace }: BootstrapContext): void { profileKey = workspace.settings.get('defaultProfile', DEFAULT_PROFILE) } + const history = { + enabled: workspace.settings.get('history.enabled', DEFAULT_HISTORY_ENABLED), + results: workspace.settings.get('history.saveResult', DEFAULT_HISTORY_SAVE_RESULT), + max: workspace.settings.get('history.maxItems', DEFAULT_HISTORY_MAX_ITEMS) + } + const profiles = workspace.settings.get('profiles', DEFAULT_PROFILES) const profile: Profile = profiles[profileKey] const result: Result = command.result + const start = Date.now() let finalize: boolean = true @@ -270,7 +280,9 @@ export function attach({ app, workspace }: BootstrapContext): void { command.complete = true command.error = result.code !== 0 - console.log('FINISH', command.prompt) + if (history.enabled) { + workspace.history.append(command, start, profileKey, history.results, history.max) + } } try { From f8cdf742acac6fed05ceaa6a89c0884ee125a87b Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 10:29:02 -0400 Subject: [PATCH 5/7] fix: update constant tests for new history constants --- src/constants.test.ts | 48 +++++++++++++++++++++++++---------- src/main/framework/history.ts | 2 +- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/constants.test.ts b/src/constants.test.ts index db44c7a..c860abe 100644 --- a/src/constants.test.ts +++ b/src/constants.test.ts @@ -1,8 +1,12 @@ +import { Profile } from './main/framework/runtime' import { DEFAULT_WORKSPACE, DEFAULT_PROFILE, DEFAULT_PROFILES, DEFAULT_FOLDER, + DEFAULT_HISTORY_ENABLED, + DEFAULT_HISTORY_MAX_ITEMS, + DEFAULT_HISTORY_SAVE_RESULT, DEFAULT_SETTING_RUNNER_SHORTCUT, DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT, DEFAULT_SETTING_IS_COMMANDER_MODE, @@ -12,17 +16,16 @@ import { } from './constants' describe('constants', () => { - it('should have the correct default workspace', () => { + it('should have the correct DEFAULT_WORKSPACE', () => { expect(DEFAULT_WORKSPACE).toBe('~/mterm') }) - it('should have the correct default profile based on platform', () => { - const expectedDefaultProfile = process.platform === 'win32' ? 'powershell' : 'sh' - expect(DEFAULT_PROFILE).toBe(expectedDefaultProfile) + it('should have the correct DEFAULT_PROFILE based on the platform', () => { + expect(DEFAULT_PROFILE).toBe(process.platform === 'win32' ? 'powershell' : 'sh') }) - it('should have the correct default profiles based on platform', () => { - const expectedDefaultProfiles = + it('should have the correct DEFAULT_PROFILES based on the platform', () => { + const expectedProfiles: Record = process.platform === 'win32' ? { powershell: { @@ -43,26 +46,38 @@ describe('constants', () => { icon: 'default' } } - expect(DEFAULT_PROFILES).toEqual(expectedDefaultProfiles) + expect(DEFAULT_PROFILES).toEqual(expectedProfiles) }) - it('should have the correct default folder', () => { + it('should have the correct DEFAULT_FOLDER', () => { expect(DEFAULT_FOLDER).toBe('$CWD') }) - it('should have the correct default setting runner shortcut', () => { + it('should have the correct DEFAULT_HISTORY_ENABLED', () => { + expect(DEFAULT_HISTORY_ENABLED).toBe(true) + }) + + it('should have the correct DEFAULT_HISTORY_MAX_ITEMS', () => { + expect(DEFAULT_HISTORY_MAX_ITEMS).toBe(100) + }) + + it('should have the correct DEFAULT_HISTORY_SAVE_RESULT', () => { + expect(DEFAULT_HISTORY_SAVE_RESULT).toBe(true) + }) + + it('should have the correct DEFAULT_SETTING_RUNNER_SHORTCUT', () => { expect(DEFAULT_SETTING_RUNNER_SHORTCUT).toBe('`+CommandOrControl') }) - it('should have the correct default setting commander mode toggle shortcut', () => { + it('should have the correct DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT', () => { expect(DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT).toBe('`+Shift+CommandOrControl') }) - it('should have the correct default setting for commander mode', () => { + it('should have the correct DEFAULT_SETTING_IS_COMMANDER_MODE', () => { expect(DEFAULT_SETTING_IS_COMMANDER_MODE).toBe(true) }) - it('should have the correct default setting for commander mode bounds', () => { + it('should have the correct DEFAULT_SETTING_COMMANDER_MODE_BOUNDS', () => { expect(DEFAULT_SETTING_COMMANDER_MODE_BOUNDS).toEqual({ screen: 0, x: 0, @@ -72,7 +87,7 @@ describe('constants', () => { }) }) - it('should have the correct default setting for runner bounds', () => { + it('should have the correct DEFAULT_SETTING_RUNNER_BOUNDS', () => { expect(DEFAULT_SETTING_RUNNER_BOUNDS).toEqual({ screen: 'PRIMARY', x: 'SCREEN:-.5', @@ -82,10 +97,15 @@ describe('constants', () => { }) }) - it('should have the correct default settings', () => { + it('should have the correct DEFAULT_SETTINGS', () => { expect(DEFAULT_SETTINGS).toEqual({ defaultProfile: DEFAULT_PROFILE, profiles: DEFAULT_PROFILES, + history: { + enabled: DEFAULT_HISTORY_ENABLED, + maxItems: DEFAULT_HISTORY_MAX_ITEMS, + saveResult: DEFAULT_HISTORY_SAVE_RESULT + }, runner: { shortcut: DEFAULT_SETTING_RUNNER_SHORTCUT, bounds: DEFAULT_SETTING_RUNNER_BOUNDS, diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts index a0072a8..c1b789a 100644 --- a/src/main/framework/history.ts +++ b/src/main/framework/history.ts @@ -1,4 +1,4 @@ -import { pathExists, readJSON, writeFile, writeJson } from 'fs-extra' +import { pathExists, readJSON, writeFile } from 'fs-extra' import { Command } from './runtime' export interface HistoricalExecution { From a9325dde8c0a6cdfd5ce43b24a2c20396d5680e3 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 11:50:20 -0400 Subject: [PATCH 6/7] fix: history scroll --- src/main/framework/history.ts | 40 +++++++++++++++------ src/main/framework/runtime-events.ts | 52 +++++++++++++++++++++++++++- src/main/framework/workspace.ts | 6 ++-- src/renderer/src/runner/runner.tsx | 12 +++++++ 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts index c1b789a..12ea44c 100644 --- a/src/main/framework/history.ts +++ b/src/main/framework/history.ts @@ -14,9 +14,13 @@ export interface HistoricalExecution { code: number } +// so why save two seperate histories? +// new execution is the history that is still pending writing +// this gives us the ability to easily scroll without exposing all the data to the front all at once export class History { - public execution: HistoricalExecution[] = [] - + public priorExecution: HistoricalExecution[] = [] + public newExecution: HistoricalExecution[] = [] + public scrollIndex: number = 0 constructor(public location: string) {} async load(): Promise { @@ -26,15 +30,11 @@ export class History { await writeFile(this.location, prettyJSON, 'utf-8') } else { - this.execution = await readJSON(this.location) + this.priorExecution = await readJSON(this.location) } } - append(command: Command, start: number, profile: string, saveResult: boolean, max: number): void { - if (this.execution.length + 1 > max) { - this.execution.shift() - } - - this.execution.push({ + append(command: Command, start: number, profile: string, saveResult: boolean): void { + this.newExecution.push({ prompt: command.prompt, aborted: command.aborted, result: saveResult ? command.result.stream.map((o) => o.raw) : undefined, @@ -48,7 +48,25 @@ export class History { }) } - async write(): Promise { - await writeFile(this.location, JSON.stringify(this.execution, null, 2)) + async write(max: number): Promise { + const history: Array = [...this.priorExecution, ...this.newExecution] + + history.sort((historyA, historyB) => historyA.when.start - historyB.when.start) + + const historyFinalList = + max > history.length ? history.slice(history.length - max, max) : history + + await writeFile(this.location, JSON.stringify(historyFinalList, null, 2)) + } + + rewind(): HistoricalExecution | undefined { + if (this.scrollIndex >= this.priorExecution.length) { + return + } + const historicalItem = this.priorExecution[this.priorExecution.length - 1 - this.scrollIndex] + + this.scrollIndex++ + + return historicalItem } } diff --git a/src/main/framework/runtime-events.ts b/src/main/framework/runtime-events.ts index 389d85d..430ca90 100644 --- a/src/main/framework/runtime-events.ts +++ b/src/main/framework/runtime-events.ts @@ -24,6 +24,7 @@ import { DEFAULT_SETTING_IS_COMMANDER_MODE } from '../../constants' import Convert from 'ansi-to-html' +import { HistoricalExecution } from './history' const convert = new Convert() const DOMPurify = createDOMPurify(new JSDOM('').window) @@ -93,6 +94,55 @@ export function attach({ app, workspace }: BootstrapContext): void { return true }) + ipcMain.handle('history.try-scroll-next', async (_, runtimeId): Promise => { + const runtime = workspace.runtimes.find((r) => r.id === runtimeId) + if (!runtime) { + return false + } + const enabled: boolean = workspace.settings.get( + 'history.enabled', + DEFAULT_HISTORY_ENABLED + ) + if (!enabled) { + return false + } + + const rewind: HistoricalExecution | undefined = workspace.history.rewind() + if (rewind === undefined) { + return false + } + + const command: Command = { + prompt: rewind.prompt, + error: rewind.error, + aborted: rewind.aborted, + runtime: runtimeId, + id: short.generate(), + complete: true, + result: { + code: rewind.code, + stream: !rewind.result + ? [] + : rewind.result.map((raw) => { + let text = raw.toString() + + text = DOMPurify.sanitize(raw) + text = convert.toHtml(text) + + return { + error: rewind.error, + raw, + text: text + } + }) + } + } + + runtime.history.push(command) + + return true + }) + ipcMain.handle('runtime.rename', async (_, runtimeId, name): Promise => { const runtime = workspace.runtimes.find((r) => r.id === runtimeId) if (!runtime) { @@ -281,7 +331,7 @@ export function attach({ app, workspace }: BootstrapContext): void { command.error = result.code !== 0 if (history.enabled) { - workspace.history.append(command, start, profileKey, history.results, history.max) + workspace.history.append(command, start, profileKey, history.results) } } diff --git a/src/main/framework/workspace.ts b/src/main/framework/workspace.ts index 3a20df5..00df01a 100644 --- a/src/main/framework/workspace.ts +++ b/src/main/framework/workspace.ts @@ -7,7 +7,7 @@ import { remove } from 'lodash' import { app, BrowserWindowConstructorOptions } from 'electron' import { setWindowValueFromPath } from '../util' import { Runtime } from './runtime' -import { DEFAULT_FOLDER, DEFAULT_HISTORY_ENABLED } from '../../constants' +import { DEFAULT_FOLDER, DEFAULT_HISTORY_ENABLED, DEFAULT_HISTORY_MAX_ITEMS } from '../../constants' import { Commands } from './commands' import { Store } from './store' import { History } from './history' @@ -166,7 +166,9 @@ export class Workspace { async persist(): Promise { const saveHistory = this.settings.get('history.enabled', DEFAULT_HISTORY_ENABLED) if (saveHistory) { - await this.history.write() + const maxHistory = this.settings.get('history.maxItems', DEFAULT_HISTORY_MAX_ITEMS) + + await this.history.write(maxHistory) } } diff --git a/src/renderer/src/runner/runner.tsx b/src/renderer/src/runner/runner.tsx index 95d4ac4..35f8c8a 100644 --- a/src/renderer/src/runner/runner.tsx +++ b/src/renderer/src/runner/runner.tsx @@ -122,6 +122,18 @@ export default function Runner(): ReactElement { if (e.code === 'ArrowUp') { if (runtime && historyIndex < runtime.history.length - 1) { applyHistoryIndex(historyIndex + 1) + } else { + window.electron.ipcRenderer + .invoke('history.try-scroll-next', runtime?.id) + .then((isHistoricalScroll: boolean) => { + if (isHistoricalScroll) { + applyHistoryIndex(historyIndex + 1) + + return reloadRuntimesFromBackend() + } + + return Promise.resolve() + }) } } From d1ae294dad3befec6ac5f27a891eec5e76269d28 Mon Sep 17 00:00:00 2001 From: DR Date: Sun, 5 May 2024 11:59:18 -0400 Subject: [PATCH 7/7] fix: make sure history can not exceed max --- src/main/framework/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/framework/history.ts b/src/main/framework/history.ts index 12ea44c..526ef7d 100644 --- a/src/main/framework/history.ts +++ b/src/main/framework/history.ts @@ -54,7 +54,7 @@ export class History { history.sort((historyA, historyB) => historyA.when.start - historyB.when.start) const historyFinalList = - max > history.length ? history.slice(history.length - max, max) : history + max < history.length ? history.slice(history.length - max, history.length) : history await writeFile(this.location, JSON.stringify(historyFinalList, null, 2)) }