gregoor / tofu Goto Github PK
View Code? Open in Web Editor NEWExperiment in structural code editing
Home Page: https://marketplace.visualstudio.com/items?itemName=watware.tofu-vscode
Experiment in structural code editing
Home Page: https://marketplace.visualstudio.com/items?itemName=watware.tofu-vscode
Atm active is always set to the end of a selection which makes range selects in Tofu look different from the native ones, which also obscures the effect of selecting next/prev within an identifier/string.
to keep resizability (i.e. printWidth changes), tofu would need to re-format when saving
Input
asd|asd
Action
&
Output
asd & |asd
Expected
asd |&| asd
Especially in function headers?
atm if you have
() => ≤null≥
and press {
, you get
() => ({})
Thus there is no way to put a block in an arrow function.
I see a few possible solutions:
()
.Enter
to add a block when null
is selected in the arrow fn body. This would set a precedent and imo should only be done if it could be useful in other contexts.;
is not used for anything yet, since we completely leave semi-colonizing to prettier. Since it symbolizes statements it would actually fit quite well. It also sets a precedent, so it'd be great to find other reasons to use it.Both 2. & 3. also both lack the WYSIWYGness that I strive for with Tofu. So I think it should be 1 after all.
Currently spawns expression-protected-parens (i.e. ({})
) which is invalid
Apparently some editors allow you to navigate by word with alt+left/alt+right, which might make it confusing that tofu uses those keys for moving statements. So maybe a different shortcut would be more appropriate.
Open questions:
After hitting space
the variable should be initialized, but now I need to manually hit a random key to finish this process.
Input
let n|
Action
space
Output
let n |
Expected
let n = |null|
Btw really like your work.
A combination of unwrap, extend selection and wrap with what was previously removed by unwrapping. Afaik Paredit has a similar feature, sth like "barfing". Should look into it. Some examples
a ? fn(≤b≥) : c
fn(≤a ? b : c≥)
{ a: [≤b≥], c }
[≤{ a: b, c }≥]
a ? f(≤b≥, c) : d
f(a ? b : d, c)
a ? f(b, ≤c≥) : d
f(≤b, a ? c : d≥)
<ErrorBoundary
fallback={<>An error occurred while searching. We are looking into it!</>}
>
{term && results && ≤<SearchResults {...{ term, results }} />≥}
</ErrorBoundary>;
{
term && results && (
<ErrorBoundary
fallback={<>An error occurred while searching. We are looking into it!</>}
>
<SearchResults {...{ term, results }} />
</ErrorBoundary>
);
}
This one is a bit more involved, and maybe it's better solved with multi-selections, which Tofu can't do yet.
({ a: t ? ≤1≥ : 2, b: t ? ≤"y"≥ : "n" });
t ? { a: 1, b: "y" } : { a: 2, b: "n" };
some ideas
I tried the former at one point, but realized that I just added complexity and bugs and ultimately reduced throughput. So another attempt should be more principled.
Input
let n|;
Action
Space
Current output
let n |;
Expected output
let n = |null|;
≤a≥;
{
b;
}
with moveNode(RIGHT)
should yield
{
≤a≥;
b;
}
No idea yet how to separate that out
what happened there buddy?
You can write infinite loops in the editor which freeze the whole page (and probably also are persisted in localStorage).
Input
asd || (|asd| && asd);
Action
Shift
+ ArrowLeft
- Range Select Previous
Current output
|asd || (asd && asd);|
Expected output
|asd || (asd| && asd);
Input
a * b|
Action
Backspace
Current output
a * |
Expected output
a
const a = [
veryLongElementInThisArrayLeadingToLineBreakAndThusTriggeringTheBug,
];
asd(23|);
,
- Add argument
const a = [
veryLongElementInThisArrayLeadingToLineBreakAndThusTriggeringTheBug,
];
asd(23, |null|);
```javascript
const a = [
veryLongElementInThisArrayLeadingToLineBreakAndThusTriggeringTheBug,
];
asd(23, |null|);
An empty new line gets added
Input
|asd|.efg;
asd;
Action
Shift + ArrowRight
- Extend selection
Output
|asd.efg;
asd;|
Expected
|asd.efg|;
asd;
Input
() => {};|
Action
ArrowLeft
- Navigate left
Output
(|) => {};
Expected
() => {|};
Should select whatever AST nodes are in that range
Input
reduce(|);
Action
(
Current output
reduce((|));
Expected output
reduce((|) => null);
Input
test(|a, b|);
Action
Shift + ArrowRight
Output
test(|a, b|);
Expected
|test(a, b)|;
Should probably only select full nodes (unless inside of a literal), like keyboard selection. Current behavior is confusing, since the select preview suggests mouse selection might work.
I really should credit them somewhere, that tool made this whole thing so much easier
Stop the editor from jumping around, what did I even think, it's annoying, like srsly
Input
call(|arg1, arg2);
Action
Backspace
- Delete
Current output
call|arg1, arg2);
Expected output
call|;
Deleting a brace / paranthese should delete the wrapping expression and put its child in its place.
Input
const a = [|23];
Action
Backspace
Output
const a = |23;
Input
fn([|23, 42]);
Action
Backspace
Output
fn([23, 42);
Input
const a = fn(|23);
Action
Backspace
Output
const a = |23;
Currently it's complicated to add statements after a block that's inside another block
Input
for (const item of iterable) {
for (const item of iterable) {|
}
}
Action
ArrowRight
- Navigate right
Output
for (const item of iterable) {
for (const item of iterable) {
}
}
|
Expected
for (const item of iterable) {
for (const item of iterable) {
}|
}
Input
let a = [|asd, asd];
Action
Backspace
Expected output
let a;
Input
fn([|asd, asd]);
Action
Backspace
Expected output
fn(|);
In the rush of adding tests I was about to add, and consequently fix this one:
it("merges array elements", async () => {
const hook = renderHook(() => useHistory("[a, b];\n"));
await queueMoveCursorFor(hook, new Range(4));
await queueActionFor(
hook,
new KeyboardEvent("keydown", { code: "Backspace" })
);
expect(hook.result.current[0].code.source).toBe("[ab];\n");
expect(hook.result.current[0].cursor.start).toBe(2);
});
After such a change tofu would turn [a, |b]
(|
denoting the cursor) into [ab]
when pressing Backspace
. While this is fine and dandy, naively implemented, it might also turn [a(), |b]
into [a()b]
which is not so dandy.
I was motivated to make this change because I introduced the reverse action, of splitting identifiers with a comma, when the cursor is inside, e.g. [a|b]
=> [a, b]
. While typing this I realized I can make Backspace only ever do what I described above, when both elements are an identifier (for function calls it could also work, but for destructuing, default parameters, yadayada, things will get complex).
Okay typing is thinking, some more thoughts developed from this, which might become a new design principle: Every additive, single keystroke action, should be revertible by pressing Backspace. The idea is here, once again, to piggyback on intuition around regular old text editing, which has this neat property of Backspace undoing the additive things one just has done.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.