Skip to content

Commit

Permalink
fix: settings cli provided
Browse files Browse the repository at this point in the history
* fix: adding `:workspace` command to open workspace folder

* fix: settings cli provided

resolves #80

* fix: add readme for system commands
  • Loading branch information
daretodave authored Apr 30, 2024
1 parent d55f310 commit f435af1
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 4 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ here is an example `~/mterm/settings.json` -
- x, y, w, h: `SCREEN:ratio | number` use a ratio of the screen size (for centering etc) or use a static number


### System

mterm provided a few system commands to help control the terminal and settings. mterm settings will always start with `:` (a colon) unless the intention is to override a system command. for example, because `clear` needs to be handled in a special way for mterm windows + tabs, it is overriden in mterm.

| Command | Alias | Purpose |
|------------------------------|--------|-----------------------------------------------------------------------------|
| `clear` | `cls` | Clear the current terminal output |
| `cd` | | Navigate the file tree on the host machine |
| `:exit` | `exit` | Exit the current tab, or mterm if only 1 tab is open |
| `:history` | | Print out terminal history for debugging in a JSON format |
| `:reload` | | Reload settings, the ui, and commands without restarting |
| `:tab` | | Open a new tab |
| `:test` | | Sample command that executes after 10 seconds. Helpful for debugging |
| `:vault` | | Open the secret management tool, the mterm vault |
| `:version` | `:v` | Print the current mterm version |
| `:workspace` | | Open the mterm workspace folder on disk: `~/mterm` |
| `:settings` | | Open the mterm settings gui to manage `~/mterm/settings.json` |
| `:settings reload` | | Reload `~/mterm/settings.json` and all ui etc associated with the settings |
| `:settings {get\|set} {key}` | | Set the setting key matching the path in `~/mterm/settings.json` and reload |

### Commands

Need your own command? MTERM includes `~/mterm/commands.ts` from your home directory - with any exported functions as available commands.
Expand Down
8 changes: 5 additions & 3 deletions src/main/framework/runtime-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ import Test from './system-commands/test'
import Clear from './system-commands/clear'
import Version from './system-commands/version'
import Vault from './system-commands/vault'
import Workspace from './system-commands/workspace'
import Settings from './system-commands/settings'

const systemCommands: Array<{
command: string
alias?: string[]
task: (context: ExecuteContext) => Promise<void> | void
}> = [Reload, Exit, History, Cd, Tab, Test, Clear, Version, Vault]
task: (context: ExecuteContext, ...args: string[]) => Promise<void> | void
}> = [Reload, Exit, History, Cd, Tab, Test, Clear, Version, Vault, Workspace, Settings]
export async function execute(context: ExecuteContext): Promise<void | boolean> {
const { platform, workspace, runtime, command, out, finish } = context
const [cmd, ...args] = command.prompt.split(' ')

// check for system commands
for (const systemCommand of systemCommands) {
if (systemCommand.command === cmd || systemCommand?.alias?.includes(cmd)) {
await systemCommand.task(context)
await systemCommand.task(context, ...args)

return
}
Expand Down
11 changes: 10 additions & 1 deletion src/main/framework/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@ export class Settings {
private properties: object = {}
private overrides: object = {}
constructor(
private location: string,
public location: string,
private defaultSettings: object
) {}

set<T>(path: string, value: T): void {
setFromPath(this.properties, path, value)
}

async save(): Promise<void> {
const prettyJSON = JSON.stringify(this.properties, null, 2)

await writeFile(this.location, prettyJSON, 'utf-8')
}
value<T>(path: string): T {
const props = merge({}, this.properties, this.overrides)
return getFromPath(props, path)
Expand Down
85 changes: 85 additions & 0 deletions src/main/framework/system-commands/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ExecuteContext } from '../runtime'
import { RunnerWindow } from '../../window/windows/runner'
import { shell } from 'electron'
import { parseInt } from 'lodash'

export default {
command: ':settings',
async task(
context: ExecuteContext,
task?: string,
key?: string,
...valueBlocks: string[]
): Promise<void> {
let value: string | boolean | number | object = valueBlocks.join(' ')
if (!task) {
await context.workspace.showAndHideOthers(RunnerWindow, 'settings/general')
}
if (task === 'reload') {
await context.workspace.settings.load()
await context.workspace.reload(RunnerWindow)

context.out(`settings reloaded`)
} else if (task === 'open') {
await shell.openPath(context.workspace.settings.location)
} else if (task === 'get') {
if (!key) {
context.out('no key provided to :settings get', true)
context.finish(1)
return
}
let value = context.workspace.settings.get(key, 'NOT FOUND')
if (typeof value === 'object') {
value = JSON.stringify(value, null, 2)
}
context.out(value)
return
} else if (task === 'set') {
if (!key) {
context.out('no key provided to :settings set', true)
context.finish(1)
return
}
if (!value) {
context.out('no value provided to :settings set', true)
context.finish(1)
return
}
const currentValue = context.workspace.settings.get(key, null)
if (currentValue !== null && typeof currentValue === 'object') {
try {
const complexValue = JSON.parse(value)
if (typeof complexValue === 'string' || typeof complexValue === 'number') {
context.out(`The value provided was a simple primitive...`)
context.out(`The current value of ${key} = \n`)
context.out(JSON.stringify(currentValue, null, 2))
context.finish(1)
return
}
value = complexValue
} catch (e) {
context.out(`The value provided could not be parsed\n\n${e}\n`)
context.out(`The current value of ${key} = \n`)
context.out(JSON.stringify(currentValue, null, 2))
context.finish(1)
return
}
} else if (currentValue !== null) {
if (typeof currentValue === 'boolean') {
value = value === 'true'
} else if (typeof currentValue === 'number') {
value = parseInt(value, 10)
}
}
const path = `${key}`

context.workspace.settings.set(path, value)

await context.workspace.settings.save()

context.out(`value '${path}' set and saved`)

await context.workspace.reload(RunnerWindow)
}
}
}
11 changes: 11 additions & 0 deletions src/main/framework/system-commands/workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ExecuteContext } from '../runtime'
import { shell } from 'electron'

export default {
command: ':workspace',
async task(context: ExecuteContext): Promise<void> {
await shell.openPath(context.workspace.folder)

context.out('opened workspace in explorer')
}
}

0 comments on commit f435af1

Please sign in to comment.