Skip to content

Commit

Permalink
move all the blank options into edit functions
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Sep 14, 2021
1 parent ccc00ce commit 7f9412c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 176 deletions.
16 changes: 9 additions & 7 deletions editor/src/components/Binary.svelte
Expand Up @@ -35,6 +35,12 @@
action = Edit.shotcut_for_binary(key, ctrlKey);
}
Option.map(action, (action) => {
if (value !== string) {
global.update_tree(
metadata.path,
Ast.binary(string.replace("<br>", "\n"))
);
}
let edit = Edit.edit(action, metadata.path);
event.preventDefault();
event.stopPropagation();
Expand All @@ -48,8 +54,7 @@
<span class="text-green-400"
>{#if multiline}
"""
{:else}
"{/if}<span
{:else}"{/if}<span
id="p{metadata.path.toArray().join(',')}"
class="{multiline ? 'block' : 'inline'} outline-none"
contenteditable=""
Expand All @@ -58,8 +63,5 @@
bind:innerHTML={string}
/>{#if multiline}
"""
{:else}
"
{/if}</span
>
<ErrorNotice type_={metadata.type_} />
{:else}"{/if}</span
><ErrorNotice type_={metadata.type_} />
151 changes: 13 additions & 138 deletions editor/src/components/Hole.svelte
@@ -1,123 +1,29 @@
<script>
import { tick, createEventDispatcher } from "svelte";
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
import ErrorNotice from "./ErrorNotice.svelte";
import { List } from "../gen/gleam";
import * as AstBare from "../gen/eyg/ast";
import * as Builders from "../gen/standard/builders";
const Ast = Object.assign({}, AstBare, Builders);
import * as Provider from "../gen/eyg/ast/provider";
import * as Pattern from "../gen/eyg/ast/pattern";
import { key_find } from "../gen/gleam/list";
import * as Edit from "../gen/eyg/ast/edit";
import * as Option from "../gen/gleam/option";
export let metadata;
export let global;
export let required = false;
let content;
function thenFocus(path) {
tick().then(() => {
let pathId = "p" + path.toArray().join(",");
let element = document.getElementById(pathId);
element?.focus();
});
}
function insertLet() {
let path = metadata.path;
let newNode = Ast.let_(Pattern.variable(""), Ast.hole(), Ast.hole());
global.update_tree(path, newNode);
thenFocus(path);
}
function insertVariable(label) {
label = label.trim().replace(" ", "_");
let path = metadata.path;
let newNode = Ast.variable(label);
global.update_tree(path, newNode);
content = "";
thenFocus(path);
}
function insertBinary() {
let path = metadata.path;
let newNode = Ast.binary("");
global.update_tree(path, newNode);
thenFocus(path);
}
function insertTuple() {
let path = metadata.path;
let newNode = Ast.tuple_(List.fromArray([]));
global.update_tree(path, newNode);
thenFocus(Ast.append_path(path, 0));
}
function insertRow() {
let path = metadata.path;
let newNode = Ast.row(List.fromArray([]));
global.update_tree(path, newNode);
thenFocus(Ast.append_path(path, 0));
}
function insertFunction() {
let path = metadata.path;
let newNode = Ast.function$(List.fromArray([]), Ast.hole());
global.update_tree(path, newNode);
thenFocus(path);
}
function insertProvider(content) {
let path = metadata.path;
let name = content.trim().replace(" ", "_");
let newNode = Provider.from_name(name);
global.update_tree(path, newNode);
thenFocus(path);
}
// scope should include equal
// Need keydown for tab to work
function handleKeydown(event) {
// tab moves to variable selection
if (event.key === "Tab" && variables.length === 0) {
if (content.trim().replace(" ", "_")) {
event.preventDefault();
insertVariable(content);
}
} else if (event.key === '"') {
event.preventDefault();
insertBinary();
} else if (event.key === "=") {
event.preventDefault();
let pattern = content.trim().replace(" ", "_");
let path = metadata.path;
let newNode = Ast.let_(Pattern.variable(pattern), Ast.hole(), Ast.hole());
global.update_tree(path, newNode);
thenFocus(Ast.append_path(path, 0));
} else if (event.key === "(") {
const { key, ctrlKey } = event;
let action = Edit.shotcut_for_blank(content, key, ctrlKey);
Option.map(action, (action) => {
let edit = Edit.edit(action, metadata.path);
event.preventDefault();
let pattern = content.trim().replace(" ", "_");
let path = metadata.path;
if (pattern) {
let newNode = Ast.call(Ast.variable(pattern), List.fromArray([]));
global.update_tree(path, newNode);
thenFocus(Ast.append_path(path, 1));
} else {
insertFunction();
}
} else if (event.key === "[") {
event.preventDefault();
insertTuple();
} else if (event.key === "{") {
event.preventDefault();
insertRow();
} else if (event.key === "<") {
event.preventDefault();
insertProvider(content);
} else if (event.key === "Backspace" && content === "") {
console.log("deleting up");
dispatch("deletebackwards", {});
}
event.stopPropagation();
dispatch("edit", edit);
});
event.stopPropagation();
}
let nodeFocused = false;
let helpFocused = false;
Expand Down Expand Up @@ -178,43 +84,12 @@
{#each variables as [key]}
<button
class="hover:bg-gray-200 px-1 outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={() => insertVariable(key)}
on:click={() =>
dispatch("edit", Edit.replace_with_variable_action(key, metadata.path))}
on:focus={focusHelp}
on:blur={tryBlur}>{key}</button
>
{/each}
<!-- <br /> -->
<!-- <span>elements:</span>
<button
class="hover:bg-gray-200 px-1 font-bold outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={insertLet}
on:focus={focusHelp}
on:blur={tryBlur}>Let</button
>
<button
class="hover:bg-gray-200 px-1 font-bold outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={insertFunction}
on:focus={focusHelp}
on:blur={tryBlur}>Function</button
>
<button
class="hover:bg-gray-200 px-1 font-bold outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={insertBinary}
on:focus={focusHelp}
on:blur={tryBlur}>Binary</button
>
<button
class="hover:bg-gray-200 px-1 font-bold outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={insertTuple}
on:focus={focusHelp}
on:blur={tryBlur}>Tuple</button
>
<button
class="hover:bg-gray-200 px-1 font-bold outline-none focus:border-gray-500 border-b-2 border-gray-100"
on:click={insertRow}
on:focus={focusHelp}
on:blur={tryBlur}>Row</button
> -->
</div>
<ErrorNotice type_={metadata.type_} />

Expand Down
2 changes: 1 addition & 1 deletion editor/src/components/Provider.svelte
Expand Up @@ -56,7 +56,7 @@
</script>
{#if Ast.is_hole(generator)}
<Hole {metadata} {global} required={true} on:deletebackwards />
<Hole {metadata} on:edit {global} required={true} on:deletebackwards />
{:else}
<span
bind:this={self}
Expand Down
30 changes: 6 additions & 24 deletions editor/src/components/Tuple.svelte
@@ -1,6 +1,5 @@
<script>
import ErrorNotice from "./ErrorNotice.svelte";
import { tick } from "svelte";
import Expression from "./Expression.svelte";
import * as Ast from "../gen/eyg/ast";
import * as Edit from "../gen/eyg/ast/edit";
Expand All @@ -12,22 +11,6 @@
export let elements;
export let global;
function thenFocus(path) {
tick().then(() => {
let pathId = "p" + path.toArray().join(",");
let element = document.getElementById(pathId);
element?.focus();
});
}
function handleDeletebackwards(_event) {
let len = elements.toArray().length;
if (len) {
thenFocus(Ast.append_path(len - 1));
} else {
global.update_tree(metadata.path, Ast.hole());
thenFocus(metadata.path);
}
}
function handleKeydown(event) {
const { key, ctrlKey } = event;
let action;
Expand All @@ -51,12 +34,11 @@
expression={element}
on:edit
{global}
/>{/each}<Hole
metadata={Object.assign({}, metadata, {
path: Ast.append_path(metadata.path, elements.toArray().length),
})}
{global}
on:deletebackwards={handleDeletebackwards}
/>]</span
/>{:else}<Hole
metadata={Object.assign({}, metadata, {
path: Ast.append_path(metadata.path, elements.toArray().length),
})}
{global}
/>{/each}]</span
>
<ErrorNotice type_={metadata.type_} />
54 changes: 48 additions & 6 deletions eyg/src/eyg/ast/edit.gleam
Expand Up @@ -3,8 +3,9 @@ import gleam/list
import gleam/option.{None, Option, Some}
import eyg/ast
import eyg/ast/pattern
import eyg/ast/provider
import standard/builders
import eyg/ast/expression.{Binary, Call, Expression, Function, Let, Tuple}
import eyg/ast/expression.{Binary, Call, Expression, Function, Let, Tuple, Provider}

pub type Path =
List(Int)
Expand All @@ -21,6 +22,7 @@ pub type Vertical {

pub type Action {
SelectParent
ReplaceExpression(Expression(Nil))
WrapTuple
WrapAssignment
WrapFunction
Expand Down Expand Up @@ -51,6 +53,7 @@ pub fn apply_edit(tree, edit) -> #(Expression(Nil), Path) {
}
#(tree, path)
}
ReplaceExpression(expression) -> #(map_node(tree, path, fn(_) {expression}), path)
WrapTuple -> wrap_tuple(tree, path)
WrapAssignment -> wrap_assignment(tree, path)
WrapFunction -> wrap_function(tree, path)
Expand Down Expand Up @@ -157,8 +160,19 @@ fn unwrap(tree: Expression(Nil), path: Path) {
}

fn clear(tree, path) {
let updated = map_node(tree, path, fn(_) { ast.hole() })
#(updated, path)
let current = get_node(tree, path)
case current {
#(_, Provider("", _)) -> case parent_path(path) {
None -> #(tree, path)
Some(#(path, index)) -> {
case get_node(tree, path) {
#(_, Tuple(elements)) -> #(ast.tuple_(list.append(list.take(elements, index), list.drop(elements, index + 1))), path)
_ -> #(map_node(tree, path, fn(_) { ast.hole() }), path)
}
}
}
_ -> #(map_node(tree, path, fn(_) { ast.hole() }), path)
}
}

fn insert_line_above(tree, path, last_index) {
Expand Down Expand Up @@ -192,6 +206,32 @@ pub fn clear_action() -> Option(Action) {
Some(Clear)
}

pub fn replace_with_variable_action(label, path) -> Edit {
Edit(ReplaceExpression(ast.variable(label)), path)
}

pub fn shotcut_for_blank(buffer, key, control_pressed) -> Option(Action) {
case key, control_pressed {
// maybe a is select all and s for select but ctrl s is definetly save
"a", True -> Some(SelectParent)
"\"", _ -> Some(ReplaceExpression(ast.binary(buffer)))
"[", _ -> Some(WrapTuple)
"=", _ -> Some(ReplaceExpression(ast.let_(pattern.Variable(buffer), ast.hole(), ast.hole())))
">", _ -> Some(WrapFunction)
"(", _ -> Some(ReplaceExpression(ast.call(ast.variable(buffer), ast.hole())))
"<", _ -> Some(ReplaceExpression(provider.from_name(buffer)))
"u", True -> Some(Unwrap)
"Delete", _ | "Backspace", _ -> Some(Clear)
// "H", True -> Some(InsertSpace(Left))
// "L", True -> Some(InsertSpace(Right))
"J", True -> Some(InsertLine(Above))
"K", True -> Some(InsertLine(Below))
"h", True -> Some(Reorder(Left))
"l", True -> Some(Reorder(Right))
_, _ -> None
}
}

pub fn shotcut_for_binary(string, control_pressed) -> Option(Action) {
case string, control_pressed {
// maybe a is select all and s for select but ctrl s is definetly save
Expand All @@ -216,9 +256,11 @@ pub fn shotcut_for_tuple(string, control_pressed) -> Option(Action) {
// maybe a is select all and s for select but ctrl s is definetly save
"a", _ -> Some(SelectParent)
// "[", True -> Some(WrapTuple)
// "=", True -> Some(WrapAssignment)
// "u", True -> Some(Unwrap)
// "Delete", True | "Backspace", True -> Some(Clear)
"=", True -> Some(WrapAssignment)
// TODO this doesn't work in a function
"u", True -> Some(Unwrap)
"Delete", True | "Backspace", True -> Some(Clear)
// TODO insert a path into an empty tuple it'self
// "H", True -> Some(InsertSpace(Left))
// "L", True -> Some(InsertSpace(Right))
// "J", True -> Some(InsertLine(Above))
Expand Down

0 comments on commit 7f9412c

Please sign in to comment.