Skip to content

Commit

Permalink
Merge branch 'main' into prompt-result-width-settingsjson-98
Browse files Browse the repository at this point in the history
  • Loading branch information
dhoffens authored Jun 11, 2024
2 parents dd014dc + aabc215 commit 3be3d12
Show file tree
Hide file tree
Showing 18 changed files with 636 additions and 68 deletions.
113 changes: 87 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<h1 align="left">mterm</h1>
<h5 align="left">An electron terminal written with TypeScript, and rendered with React.</h5>
<h5 align="left">Join us on discord @ <a href=https://discord.gg/mterm">discord.gg/mterm</a></h5>
Expand All @@ -16,6 +15,7 @@
this means commands such as `ls`, `cd` or program commands such as `node -v` or `yarn install` will work out of the box as long as the host machine supports these commands. you can configure the desired interpreter [below](#configure)

### Why

- by no means does mterm replace your sh, or pwsh but we think abstractions such as [secrets](#secrets), and [commands](#commands) can supplement your development routines
- in other words, instead of building a utility for a dev task in a shell script for local use, use typescript
- mterm comes with tabs but also within the scope of a tab; each command is ran in the background - this means you can use your keyboard to hop around execution stacks
Expand All @@ -25,6 +25,23 @@ this means commands such as `ls`, `cd` or program commands such as `node -v` or

Head over to the [release page](https://github.com/mterm-io/mterm/releases/latest) to find the binary for your system type. mterm is evergreen and updates are automatically installed on your system as hey get released. Run `:v` to see your current mterm version.

### Customize

mterm is customizable in a few ways -
- add your own [commands](#commands) to the terminal
- quick add a command with `:cmd command_name` and edit this
- add extensions to the terminal
- quick add an extension with `ext add mterm-red`, see [extensions](./docs/extensions.md) for more info
- change the [theme](#theme) of the terminal
- quick change the theme with `:theme` or `:css`
- change the [settings](#settings) of the terminal
- quick change the settings with `:settings edit`
- change the [profile](#configure) of the terminal to a desired interpreter
- quick change the profile with `:settings set defaultProfile wsl` (change wsl with the desired profile)


https://github.com/mterm-io/mterm/assets/7341502/c920853f-1f27-4ef9-ae72-945f1663e36d

### Autocomplete

Start typing, mterm will pick up your available: programs, [system commands](#system), [custom commands](#commands) and history
Expand All @@ -35,18 +52,21 @@ Finally, hit tab to finish the completion -
### Command Mode

By default, **mterm** opens in command mode (you can change this in [settings](#settings)). A couple of notes about command mode -

- This window is always on top
- This window follows to any desktop
- The font and theme is larger to account for large size

This is a nice way to focus on execution details but it can be annoying if multiple windows are in use.

Hide mterm with the default toggle hotkey -

```bash
~ + CommandOrControl
```

Disable command mode and go to normal terminal window mode with -

```bash
~ + Shift + CommandOrControl
```
Expand All @@ -58,16 +78,19 @@ Or change the behaviour of all of this with [settings](#settings).
mterm creates the `mterm` folder on a host machine on first launch a the user's home directory

for windows -

```bash
C:/Users/<YOUR_NAME>/mterm
```

for mac -

```bash
/Users/<YOUR_NAME>/mterm
```

for everything else -

```bash
/home/<YOUR_NAME>/mterm
```
Expand Down Expand Up @@ -133,49 +156,75 @@ here is an example `~/mterm/settings.json` -
- screen: `PRIMARY | number`, use the primary monitor or use the desired screen #
- 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 |
| `:edit` | `edit` | Open the in-terminal editor with the file provided. Hit `Ctrl+S` to save in the editor |
| `: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` |
| `:theme` | `:css` | Edit the terminal theme real time |
| `:settings` | | Open the mterm settings gui to manage `~/mterm/settings.json` |
| `:settings edit` | | Open the `~/mterm/settings.json` in the terminal editor with hot reloading |
| `: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 |
| 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 |
| `:edit` | `edit` | Open the in-terminal editor with the file provided. Hit `Ctrl+S` to save in the editor |
| `: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` |
| `:theme` | `:css` | Edit the terminal theme real time |
| `:cmd` | `:commands` | Edit the command file |
| `:cmd {cmd_name}` | | Edit the command file for the cmd_name, creates if this doesn't exist |
| `:settings` | | Open the mterm settings gui to manage `~/mterm/settings.json` |
| `:settings edit` | | Open the `~/mterm/settings.json` in the terminal editor with hot reloading |
| `: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.

Here an example -

```typescript
import * as os from 'node:os'

export function hello(name: string = os.userInfo().username): string {
return `Hi, ${name}`
}
````
```

Now run `hello X` from mterm -

![image](https://github.com/mterm-io/mterm/assets/7341502/a042d214-e528-41bd-929c-5f3de6d994cd)

> In this case, no argument was provided so the `os.userInfo().username` was the fallback. `Hello, DR` is the result!
Note: commands are in snake case always when running. `helloWorld` will be `hello_world` when running in mterm. however, mterm will still resolve `helloWorld` as `hello_world` when running - it's just important to note this when dealing with name collisions. every command is stored in snake case.

#### add a command

add a command to and edit this command -

```bash
:cmd command_name
```
![image](https://github.com/mterm-io/mterm/assets/7341502/619706da-fe9e-4a97-8786-ce294492d8af)

`command_name` is now available to mterm (or `commandName` or `COMMAND_NAME` - note all names are resolved to `snake_case`)

#### editing a command

in the same fasion you add a command, edit a command with the same syntax -
```bash
:cmd command_name
```

this editor will save with `Ctrl+S` and reload the command every time you save.


#### other notes on commands
Try fetching data!

```typescript
Expand All @@ -193,9 +242,21 @@ export async function query(): Promise<{

<img src="https://github.com/mterm-io/mterm/assets/7341502/df8e74d4-896c-4964-861d-bad3ced17c80" alt="drawing" width="500"/>


> Note the return type is optional, just added above to highlight the typescript engine provided
### Utilities

Shell (https://www.electronjs.org/docs/latest/api/shell) is provided within the command context, use shell like this:

to open folder or file:
`await this.shell.openPath(path)`

to open URL:
`await this.shell.openExternal(path)`

to open editor
`await shell.openPath(`${editorCommand} ${filePath}`)`

### Transformers
Sometimes we need to change variables, execution results or perform an operation on strings.

Expand Down Expand Up @@ -372,14 +433,13 @@ The mterm vault is an `AES-256` encrypted store on your local machine. During se

Every time `mterm` is launched, the password is required to use these values provided. You can find vault values by using `this.vault.get` in commands -

````typescript
```typescript
export function who() {
const name = this.vault.get('NAME')

return `name: ${name}`
}

````
```

![image](https://github.com/mterm-io/mterm/assets/7341502/76b26a62-33ea-4883-b07c-677f99ab3355)

Expand All @@ -391,7 +451,6 @@ mterm provides an editor with `:edit <FILE>` or `edit <FILE>` commands -

hit `control + s` within the file editor to save this


### Other Notes

When you change the tab name to include `$idx` - this will be replaced with the current tab index
Expand Down Expand Up @@ -424,11 +483,13 @@ git clone [email protected]:mterm-io/mterm.git
```

install deps -

```bash
yarn
```

run locally -

```bash
$ yarn dev
```
Expand Down
18 changes: 18 additions & 0 deletions docs/extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Known Extensions

> Please make a pull request to add your extension to this list
- [mterm-ext-red](#mterm-ext-red)
- more...


### mterm-ext-red

> source: https://github.com/mterm-io/mterm-ext-red
```bash
ext add mterm-red
```
Make your terminal (mterm) red 10 seconds -

![red terminal](https://github.com/mterm-io/mterm-ext-red/blob/HEAD/info.png?raw=true)

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,6 @@
"ts-jest": "^29.1.2",
"typescript": "^5.4.5",
"vite": "^5.0.12"
}
},
"packageManager": "[email protected]+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}
6 changes: 3 additions & 3 deletions src/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('constants', () => {
})

it('should have the correct DEFAULT_HISTORY_MAX_ITEMS', () => {
expect(DEFAULT_HISTORY_MAX_ITEMS).toBe(100)
expect(DEFAULT_HISTORY_MAX_ITEMS).toBe(1000)
})

it('should have the correct DEFAULT_HISTORY_SAVE_RESULT', () => {
Expand All @@ -74,7 +74,7 @@ describe('constants', () => {
})

it('should have the correct DEFAULT_SETTING_IS_COMMANDER_MODE', () => {
expect(DEFAULT_SETTING_IS_COMMANDER_MODE).toBe(true)
expect(DEFAULT_SETTING_IS_COMMANDER_MODE).toBe(false)
})

it('should have the correct DEFAULT_SETTING_COMMANDER_MODE_BOUNDS', () => {
Expand All @@ -92,7 +92,7 @@ describe('constants', () => {
screen: 'PRIMARY',
x: 'SCREEN:-.5',
y: 'SCREEN:-.5',
w: 720,
w: 820,
h: 500
})
})
Expand Down
6 changes: 3 additions & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export const DEFAULT_PROFILES: Record<string, Profile> =
export const DEFAULT_FOLDER = '$CWD'
export const DEFAULT_HISTORY_ENABLED = true

export const DEFAULT_HISTORY_MAX_ITEMS = 100
export const DEFAULT_HISTORY_MAX_ITEMS = 1000
export const DEFAULT_HISTORY_SAVE_RESULT = true
export const DEFAULT_SETTING_RUNNER_SHORTCUT = '`+CommandOrControl'
export const DEFAULT_SETTING_RESULTCOLWIDTH = '50%'
export const DEFAULT_SETTING_COMMANDER_MODE_TOGGLE_SHORTCUT = '`+Shift+CommandOrControl'
export const DEFAULT_SETTING_IS_COMMANDER_MODE = true
export const DEFAULT_SETTING_IS_COMMANDER_MODE = false
export const DEFAULT_SETTING_COMMANDER_MODE_BOUNDS = {
screen: 0,
x: 0,
Expand All @@ -45,7 +45,7 @@ export const DEFAULT_SETTING_RUNNER_BOUNDS = {
screen: 'PRIMARY',
x: 'SCREEN:-.5',
y: 'SCREEN:-.5',
w: 720,
w: 820,
h: 500
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/framework/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isAbsolute, join, parse } from 'path'
import { Runtime } from './runtime'
import { HistoricalExecution } from './history'
import { SystemCommand, systemCommands } from './runtime-executor'
import { Commands } from './commands'

export interface PathParts {
path: string
Expand Down Expand Up @@ -291,8 +292,8 @@ export class Autocomplete {
(o) => o.command.startsWith(prompt) || o.alias?.find((o) => o.startsWith(prompt))
)

const userCommandMatches = Object.keys(this.workspace.commands.lib).filter((o) =>
o.startsWith(prompt)
const userCommandMatches = Object.keys(this.workspace.commands.lib).filter(
(o) => o.startsWith(prompt) || o.startsWith(Commands.toCommandName(prompt))
)

const programMatches = this.programList.filter(
Expand Down
3 changes: 3 additions & 0 deletions src/main/framework/command-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class CommandUtils {
// this gets exposed as this.util
}
Loading

0 comments on commit 3be3d12

Please sign in to comment.