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