diff --git a/src/actions.ts b/src/actions.ts index 6e5c3bf..6689303 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -265,10 +265,8 @@ export const findActions = (code: Code, cursor: Range) => ({ : [], }); -const modifieresPressed = (action: BaseAction, event: KeyboardEvent) => - modifierKeys.every((key) => - action.on && key in action.on ? action.on[key] == event[key] : true - ); +const modifieresPressed = (on: BaseAction["on"], event: KeyboardEvent) => + modifierKeys.every((key) => (on && key in on ? on[key] == event[key] : true)); export function findAction(code: Code, cursor: Range, event: KeyboardEvent) { for (const action of getBaseActions(code, cursor)) { @@ -277,7 +275,7 @@ export function findAction(code: Code, cursor: Range, event: KeyboardEvent) { ("code" in action.on ? action.on.code === event.code : action.on.key === event.key) && - modifieresPressed(action, event) + modifieresPressed(action.on, event) ) { return () => action.do(code, cursor, event.shiftKey); } @@ -291,10 +289,11 @@ export function findAction(code: Code, cursor: Range, event: KeyboardEvent) { for (const action of actions) { if ( action.on && - ("code" in action.on - ? action.on.code === event.code - : action.on.key === event.key) && - modifieresPressed(action, event) + (Array.isArray(action.on) ? action.on : [action.on]).some( + (on) => + ("code" in on ? on.code === event.code : on.key === event.key) && + modifieresPressed(on, event) + ) ) { return () => action.do(); } diff --git a/src/nodes/expressions.ts b/src/nodes/expressions.ts index d567cc8..3c37f45 100644 --- a/src/nodes/expressions.ts +++ b/src/nodes/expressions.ts @@ -222,10 +222,11 @@ export const expressions: NodeDefs = { }, }, StringLiteral: { - hasSlot: (node, start) => start > node.start!, + hasSlot: (node, start) => true, }, TemplateLiteral: { hasSlot: () => true }, - TemplateElement: { hasSlot: () => true }, + BooleanLiteral: { hasSlot: selectNode }, + NullLiteral: { hasSlot: selectNode }, Identifier: { hasSlot: () => true }, @@ -240,6 +241,13 @@ export const expressions: NodeDefs = { }, actions: changeOperationActions, }, + LogicalExpression: { + hasSlot(node, start, { source }) { + const range = selectOperator(node, source); + return range.includes(start) ? range : false; + }, + actions: changeOperationActions, + }, ArrayExpression: { hasSlot(node, start) { diff --git a/src/nodes/index.ts b/src/nodes/index.ts index e446010..de668fb 100644 --- a/src/nodes/index.ts +++ b/src/nodes/index.ts @@ -20,57 +20,6 @@ import { } from "./utils"; const nodeDefs: NodeDefs = { - BooleanLiteral: { hasSlot: selectNode }, - NullLiteral: { hasSlot: selectNode }, - StringLiteral: { hasSlot: (node, start) => node.start !== start }, - - BinaryExpression: { - hasSlot(node, start, { source }) { - const operator = selectOperator(node, source); - return operator.includes(start) ? operator : false; - }, - }, - LogicalExpression: { - hasSlot(node, start, { source }) { - const operator = selectOperator(node, source); - return operator.includes(start) ? operator : false; - }, - }, - - VariableDeclaration: { - hasSlot(node, start) { - const kindRange = selectKind(node); - return kindRange.includes(start) ? kindRange : false; - }, - actions: ({ node, code, cursor }) => - selectKind(node).equals(cursor) - ? (["const", "let", "var"] as const) - .filter((kind) => node.kind != kind) - .map((kind) => ({ - info: { type: "CHANGE_DECLARATION_KIND", kind }, - on: { code: "Key" + kind[0].toUpperCase() }, - do: () => ({ - code: code.replaceSource( - new Range(node.start!, node.start! + node.kind.length), - kind - ), - nextCursor: ({ ast }, { start }) => - selectKind(getNode(ast, start) as typeof node), - }), - })) - : null, - }, - VariableDeclarator: { - actions: ({ node, path, code }) => - node.init && { - on: { code: "Space" }, - do: () => ({ - code: code.replaceSource(new Range(node.end!), "= null"), - nextCursor: ({ ast }) => selectNodeFromPath(ast, [...path, "init"]), - }), - }, - }, - ...expressions, ...statements, }; diff --git a/src/nodes/statements.ts b/src/nodes/statements.ts index 531b8ea..8b914f0 100644 --- a/src/nodes/statements.ts +++ b/src/nodes/statements.ts @@ -1,7 +1,7 @@ import t from "@babel/types"; -import { getNodeFromPath } from "../ast-utils"; -import { selectNode, selectNodeFromPath } from "../cursor/utils"; +import { getNode, getNodeFromPath } from "../ast-utils"; +import { selectKind, selectNode, selectNodeFromPath } from "../cursor/utils"; import { Range } from "../utils"; import { NodeDefs } from "./utils"; @@ -28,13 +28,36 @@ export const statements: NodeDefs = { })), }, + VariableDeclaration: { + hasSlot(node, start) { + const kindRange = selectKind(node); + return kindRange.includes(start) ? kindRange : false; + }, + actions: ({ node, code, cursor }) => + selectKind(node).equals(cursor) + ? (["const", "let", "var"] as const) + .filter((kind) => node.kind != kind) + .map((kind) => ({ + info: { type: "CHANGE_DECLARATION_KIND", kind }, + on: { code: "Key" + kind[0].toUpperCase() }, + do: () => ({ + code: code.replaceSource( + new Range(node.start!, node.start! + node.kind.length), + kind + ), + nextCursor: ({ ast }, { start }) => + selectKind(getNode(ast, start) as typeof node), + }), + })) + : null, + }, VariableDeclarator: { actions: ({ node, path, code, cursor }) => !node.init && cursor.start == node.id.end! && { - on: { key: "=" }, + on: [{ code: "Space" }, { key: "=" }], do: () => ({ - code: code.replaceSource(cursor, "= null"), + code: code.replaceSource(new Range(node.end!), "= null"), nextCursor: ({ ast }) => selectNodeFromPath(ast, [...path, "init"]), }), }, diff --git a/src/nodes/utils.ts b/src/nodes/utils.ts index 68edd9f..3c63c9b 100644 --- a/src/nodes/utils.ts +++ b/src/nodes/utils.ts @@ -5,7 +5,7 @@ import { Change, KeyConfig, Range } from "../utils"; export type NodeAction = { info?: any; - on?: KeyConfig; + on?: KeyConfig | KeyConfig[]; do: () => Change; }; export type NodeActions = false | null | NodeAction | NodeActions[];