Customizing the Prompt in Mini Micro
Tags: miniscript, minimicro, beginners, programming
Published: 2023-07-23 20:19:11

Though [Mini Micro](https://miniscript.org/MiniMicro/) is a modern virtual machine, it shares some design features with classic home computers of the '80s era.  Most noticeable of these is that it boots into a _prompt_, which is a short string next to a blinking cursor.

![animated GIF of prompt and blinking cursor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xru6tc6p59gdt8ta0xun.gif)

The purpose of the prompt is to make it clear that anything you type is going to the command shell (which in Mini  Micro's case, means the [MiniScript](https://miniscript.org) [read-eval-print loop](https://miniscript.org/wiki/REPL)), rather than to some running program that is asking for input.

By default, the prompt in Mini Micro is a right square-bracket, as you can see in the image above.  But did you know that **you can change this prompt**?  You can make it any text you like, and beyond that, you can even write code to dynamically change the prompt.  This article will show how and give several examples, from simple to fancy.

## Changing the Prompt Strings

Let's start with the simplest case: maybe you don't like the square bracket because that's also used in MiniScript syntax (for indexing into things, e.g. `"Howdy"[:3]`).  Perhaps you'd prefer the pound (hashtag) sign, which has no use in MiniScript syntax.  Just type:

```
env.prompt = "#"
```

![env.prompt = "#"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kc1ztsj5y1jz74s83sj.gif)

Or you could use some even more obscure character, like those you find in /sys/demo/specialChars.  For example, try:

```
env.prompt = char(57888)
```

![env.prompt = char(57888)
](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3s91u5dnvrhlum1bia09.gif)

Any string you assign to `env.prompt` will appear as the command prompt until you assign something else (or quit Mini Micro).  It doesn't have to be a single character; if your name is Jen, perhaps you'd like "Hello Jen!" as your prompt.  Go wild!

## Remember the "more" prompt

The MiniScript REPL actually uses _two_ prompts: the standard one we've shown so far, and a second one used when the REPL needs more input, for example because you have started an `if` block or `for` loop.  This second prompt is "...]" by default.

![for loop on the command line](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sa5u73q2qjlasxlq9rse.png)

But you can override this "more input needed" prompt as well, by assigning to `env.morePrompt`.  For example, again referring to /sys/demo/specialChars, you could choose to use a 1-spot die for the main prompt and a 3-spot die (reminiscent of "...") for the morePrompt:

```
env.prompt = char(9856)
env.morePrompt = char(9858)
```

![Dice prompts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxqpo1ci7jvna95icq9m.png)


## Updating the startup script

To keep your custom prompt working even after you restart Mini Micro, you'll want to put it into your [startup script](https://miniscript.org/wiki/How_to_run_a_program_on_startup).  Use `cd` to ensure the current directory is /usr.  Then, if you already have a /usr/startup.ms file, `edit "startup"` will launch the editor with that file.  If not, just do `edit` to edit a new program, and save it as "startup".  In either case, type some code like the following into your startup script:

```
// set a custom prompt
env.prompt = char(57888)
```

Be sure to `save` this program so it'll be there for you the next time you run Mini Micro.  Also `run` the program once to make sure your changes are applied right away.  Note that you can save and run directly from the code editor, using the buttons at the top (or their keyboard shortcuts); or you can close the editor and use the `save` and `run` commands on the command line.

## Making a prompt function

Instead of assigning just a simple string, you can assign a function to `env.prompt`.  This function can do anything you like, as long as it returns quickly.  If it returns a string, that string will be displayed as the prompt in the usual way.  Or, your function can do its own printing.

For example, here's an example that prints the prompt in a darker color, by interpolating between the current text color and the text background color.

```
env.prompt = function
	c = text.color
	text.color = color.lerp(c, text.backColor)
	print "]", ""
	text.color = c
end function
```

Running this code causes the prompt to fade nicely into the background, so you can focus your attention on the MiniScript code.

![A faded prompt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zopq3g5xmhamlklwfxr.gif)

Or, perhaps you always want to know what time it is?  You could have your prompt display the time!

```
env.prompt = function
	return _dateStr[-8:] + ">"
end function
```

![Time prompt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fy686bzvwbla7om3jxvc.gif)

(Note that this directly uses the `_dateStr` function normally wrapped by the /sys/lib/dateTime module, but we can't count on having that module available for the prompt function, so we use `_dateStr` directly here.)

Or if you're like me, you have a lot of directories and subdirectories, and sometimes forget which one you're in.  Try this prompt function to display the current directory in your prompt:

```
env.prompt = function
	return file.curdir + "]"
end function
```

If you find that creates a prompt that is too long, then consider this version, which shows just the last part of the current directory:

```
env.prompt = function
	d = file.curdir
	if d[-1] == "/" then d = d[:-1]
	return d.split("/")[-1] + "]"
end function
```

![Directory prompt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgwbhxg8svey8tp8dvcf.gif)

## Getting Fancy

Your prompt and morePrompt functions don't have to restrict themselves to printing something for the prompt itself; they can do anything, as long as they do it very quickly.  (If a prompt function takes too long to execute, Mini Micro will cancel it and display no prompt at all.)

The longer startup script below creates a prompt function that draws a status bar, showing the current directory as well as the date/time, at the top of the screen in display layer 1.  It also draws the standard prompt, but in a different color, and does the same for the "more" prompt.  Finally, it replaces the standard `clear` method (normally defined in /sys/lib/startup.ms) with one that leaves display layer 1 alone, and resets the text cursor to row 24, since row 25 is now under the status bar.

```
env.prompt = function
	now = _dateStr
	s = file.curdir + " " * 68
	s = s[:68-now.len] + now
	display(1).mode = displayMode.text
	display(1).backColor = color.clear
	display(1).clear
	display(1).row = 25; display(1).column = 0
	display(1).color = color.black
	display(1).backColor = "#6666CC"
	display(1).print s
	c = text.color
	text.color = color.lerp(c, text.backColor)
	print "]", ""
	text.color = c
	return "?!?"
end function

env.morePrompt = function
	c = text.color
	text.color = color.lerp(c, text.backColor)
	print "...]", ""
	text.color = c
	return "?!?"
end function

clear = function
	display(0).mode = displayMode.off
	display(2).mode = displayMode.off
	display(3).mode = displayMode.text
	display(3).clear
	display(4).mode = displayMode.sprite
	display(4).clear
	display(5).mode = displayMode.pixel
	display(5).clear "#00000D", 960, 640
	display(6).mode = displayMode.off
	display(7).mode = displayMode.solidColor
	display(7).color = "#000000"
	globals.text = display(3)
	globals.gfx = display(5)
	text.row = 24
end function
```

The result looks like this:

![Screen shot of fancy prompt function in action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avhzddltwot6gm9wpgz4.png)

I hope this gives you some ideas!  Take the time to play around with the examples above, and find prompts that best suit your own preferences.  Let me know in the comments what you decide to do!