Improved history & highlighting
parent
78cc118bfc
commit
48e7d405dd
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"appendleft",
|
||||
"autochurch",
|
||||
"delmac",
|
||||
"Endnodes",
|
||||
|
|
11
README.md
11
README.md
|
@ -48,6 +48,8 @@ There are many useful macros in [macros.lamb](./macros.lamb). Load them with the
|
|||
==> :load macros.lamb
|
||||
```
|
||||
|
||||
You may use up/down arrows to recall history.
|
||||
|
||||
Have fun!
|
||||
|
||||
-------------------------------------------------
|
||||
|
@ -66,7 +68,12 @@ Lamb understands many commands. Prefix them with a `:` in the prompt.
|
|||
|
||||
`:mdel [macro]` Delete a macro
|
||||
|
||||
`:step [yes | no]` Enable or disable step-by-step reduction. Toggle if no argument is given.
|
||||
`:step [yes | no]` Enable or disable step-by-step reduction. Toggle if no argument is given. When reducing by steps, the prompt tells you what kind of reduction was done last:
|
||||
|
||||
- `M`: Macro expansion
|
||||
- `C`: Church expansion
|
||||
- `H`: History expansion
|
||||
- `F`: Function application
|
||||
|
||||
`:expand [yes | no]` Enable or disable full expansion. Toggle if no argument is given. If full expansion is enabled, ALL macros will be expanded when printing output.
|
||||
|
||||
|
@ -81,7 +88,6 @@ The lines in a file look exactly the same as regular entries in the prompt, but
|
|||
|
||||
|
||||
## Todo (pre-release, in this order):
|
||||
- History queue
|
||||
- Prevent macro-chaining recursion
|
||||
- Update screenshot
|
||||
- Update documentation
|
||||
|
@ -91,7 +97,6 @@ The lines in a file look exactly the same as regular entries in the prompt, but
|
|||
|
||||
## Todo:
|
||||
- Cleanup warnings
|
||||
- Syntax highlight printouts
|
||||
- Truncate long expressions in warnings
|
||||
- History indexing
|
||||
- Show history command
|
||||
|
|
|
@ -162,14 +162,13 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> list:
|
|||
it = iter(root)
|
||||
for s, n in it:
|
||||
if isinstance(n, lbn.History):
|
||||
if len(root.runner.history) == 0:
|
||||
if root.runner.history[0] == None:
|
||||
raise lbn.ReductionError("There isn't any history to reference.")
|
||||
else:
|
||||
warnings += [
|
||||
("class:code", "$"),
|
||||
("class:warn", " will be expanded to "),
|
||||
("class:code", f"{n.expand()[1]}\n"),
|
||||
]
|
||||
("class:warn", " will be expanded to ")
|
||||
] + lamb.utils.lex_str(str(n.expand()[1]))
|
||||
|
||||
# If this expression is part of a macro,
|
||||
# make sure we don't reference it inside itself.
|
||||
|
|
|
@ -321,12 +321,12 @@ class History(ExpandableEndNode):
|
|||
def expand(self) -> tuple[lbn.ReductionType, Node]:
|
||||
# We shouldn't ever get here, prepare()
|
||||
# catches empty history.
|
||||
if len(self.runner.history) == 0:
|
||||
if self.runner.history[0] == None:
|
||||
raise Exception(f"Tried to expand empty history.")
|
||||
# .left is VERY important!
|
||||
# self.runner.history will contain Root nodes,
|
||||
# and we don't want those *inside* our tree.
|
||||
return lbn.ReductionType.HIST_EXPAND, lbn.clone(self.runner.history[-1].left)
|
||||
return lbn.ReductionType.HIST_EXPAND, lbn.clone(self.runner.history[0].left)
|
||||
|
||||
def copy(self):
|
||||
return History(runner = self.runner)
|
||||
|
|
|
@ -234,9 +234,8 @@ def cmd_load(command, runner):
|
|||
|
||||
printf(
|
||||
FormattedText([
|
||||
("class:ok", f"Loaded {x.label}: "),
|
||||
("class:code", str(x.expr))
|
||||
]),
|
||||
("class:ok", f"Loaded {x.label}: ")
|
||||
] + lamb.utils.lex_str(str(x.expr))),
|
||||
style = lamb.utils.style
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ from prompt_toolkit.formatted_text import FormattedText
|
|||
from prompt_toolkit.key_binding import KeyBindings
|
||||
from prompt_toolkit import prompt
|
||||
from prompt_toolkit import print_formatted_text as printf
|
||||
import enum
|
||||
import collections
|
||||
import math
|
||||
import time
|
||||
|
||||
|
@ -58,7 +58,10 @@ class Runner:
|
|||
# so that all digits appear to be changing.
|
||||
self.iter_update = 231
|
||||
|
||||
self.history: list[lamb.nodes.Root] = []
|
||||
self.history = collections.deque(
|
||||
[None] * 10,
|
||||
10)
|
||||
|
||||
|
||||
# If true, reduce step-by-step.
|
||||
self.step_reduction = False
|
||||
|
@ -160,10 +163,9 @@ class Runner:
|
|||
try:
|
||||
s = prompt(
|
||||
message = FormattedText([
|
||||
("class:muted", lamb.nodes.reduction_text[red_type]),
|
||||
("class:muted", f":{k:03} "),
|
||||
("class:text", str(node)),
|
||||
]),
|
||||
("class:prompt", lamb.nodes.reduction_text[red_type]),
|
||||
("class:prompt", f":{k:03} ")
|
||||
] + lamb.utils.lex_str(str(node))),
|
||||
style = lamb.utils.style,
|
||||
key_bindings = step_bindings
|
||||
)
|
||||
|
@ -218,9 +220,8 @@ class Runner:
|
|||
only_macro
|
||||
):
|
||||
out_text += [
|
||||
("class:ok", "\n\n => "),
|
||||
("class:text", str(node)), # type: ignore
|
||||
]
|
||||
("class:ok", "\n\n => ")
|
||||
] + lamb.utils.lex_str(str(node))
|
||||
|
||||
|
||||
printf(
|
||||
|
@ -230,7 +231,12 @@ class Runner:
|
|||
|
||||
# Save to history
|
||||
# Do this at the end so we don't always fully expand.
|
||||
self.history.append(lamb.nodes.expand(node, force_all = True)[1])
|
||||
self.history.appendleft(
|
||||
lamb.nodes.expand( # type: ignore
|
||||
node,
|
||||
force_all = True
|
||||
)[1]
|
||||
)
|
||||
|
||||
def save_macro(
|
||||
self,
|
||||
|
|
|
@ -4,6 +4,7 @@ from prompt_toolkit.lexers import Lexer
|
|||
from prompt_toolkit.key_binding import KeyBindings
|
||||
from prompt_toolkit import print_formatted_text as printf
|
||||
from importlib.metadata import version
|
||||
from prompt_toolkit.document import Document
|
||||
|
||||
import re
|
||||
|
||||
|
@ -77,6 +78,10 @@ class LambdaLexer(Lexer):
|
|||
return inner
|
||||
|
||||
|
||||
|
||||
def lex_str(s: str) -> list[tuple[str, str]]:
|
||||
return LambdaLexer().lex_document(Document(s))(0)
|
||||
|
||||
def show_greeting():
|
||||
# | _.._ _.|_
|
||||
# |_(_|| | ||_)
|
||||
|
|
Reference in New Issue