Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: insert logic and multi node insert issue #1148

Closed
wants to merge 4 commits into from

Conversation

SonyLeo
Copy link
Contributor

@SonyLeo SonyLeo commented Feb 25, 2025

English | 简体中文

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • Built its own designer, fully self-validated

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Background and solution

What is the current behavior?

  1. insert 节点 部分逻辑缺失
  2. 多选节点 复制 后 粘贴 到新容器报错

Issue Number: N/A

What is the new behavior?

  1. insert 节点补充相应逻辑
  2. 多选节点 复制 后 正常粘贴 到新容器

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Improved node placement: New elements are now consistently positioned at the beginning when no reference is provided.
    • Enhanced clipboard functionality: Supports pasting multiple nodes and introduces a structured copy operation.
  • Refactor

    • Streamlined clipboard operations by consolidating multiple handlers, removing redundant procedures.
    • Updated input handling for clipboard schema to ensure robust data management.
    • Minor formatting adjustment in the code structure for clarity.

Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

Walkthrough

This pull request updates the node insertion logic and clipboard handling. In the canvas API, the insertion index now defaults to 0 when a reference node is not found, and the behavior of 'before' and 'default' cases has been adjusted. In the container module, a blank line was removed for formatting, and the clipboard functionality has been enhanced to support multi-selected nodes with new copy and paste logic while removing redundant functions.

Changes

File(s) Change Summary
packages/canvas/DesignCanvas/src/api/useCanvas.js Modified insertion logic: In useCanvas.js, node insertion now defaults to the beginning if the reference is not found.
packages/canvas/container/src/container.js Formatting change: Removed a blank line in the getRect function.
packages/canvas/container/src/keyboard.js Enhanced clipboard operations: Updated handleClipboardPaste to accept a list of nodes, removed handleMultiNodesPaste, added handleCopyEvent, and updated event handlers accordingly.
packages/canvas/container/src/utils.js Updated setClipboardSchema to accept a string instead of an object, and refined input validation in translateStringToSchema.

Possibly related PRs

  • fix: add slots fail #1140: The changes in the main PR and the retrieved PR both modify the logic for inserting nodes in the operationTypeMap.insert function, specifically addressing how the referTargetNodeId is handled when determining the insertion position.
  • fix: TinyGrid slot children can not operate #1100: The changes in the main PR modify the logic for inserting nodes in the insert method of useCanvas.js, while the retrieved PR introduces new functions for handling nodes in the same file, indicating a direct relationship in their functionality regarding node management.
  • fix: canvasDivider can't work #1075: The changes in the main PR, which modify the logic for inserting nodes into the parentNode.children array, are related to the retrieved PR as both involve operations on the children array of canvas nodes, specifically in the context of updating and managing node structures.

Suggested labels

refactor-main

Suggested reviewers

  • hexqi
  • chilingling
  • rhlin

Poem

I'm a coding rabbit, hopping with delight,
Tweaking node insertions from morning till night.
With clipboard flows dancing in sync so clear,
Each change a little carrot bringing cheer.
Hop along the code trail—adventure is here!

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/canvas/container/src/keyboard.js

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "@typescript-eslint/eslint-plugin".

(The package "@typescript-eslint/eslint-plugin" was not found when loaded as a Node module from the directory "/packages/canvas".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install @typescript-eslint/eslint-plugin@latest --save-dev

The plugin "@typescript-eslint/eslint-plugin" was referenced from the config file in "packages/canvas/.eslintrc.cjs » @vue/eslint-config-typescript".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Tip

CodeRabbit's docstrings feature is now available as part of our Pro Plan! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the bug Something isn't working label Feb 25, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/canvas/container/src/container.js (1)

331-350: Improved insertion logic with flexible target

The enhanced insertAfter function now accepts a target parameter, providing more control over insertion. The addition of conditional logic to include referTargetNodeId when no target is specified improves how nodes are referenced during insertion operations.

Consider adding a comment explaining the difference between using the target vs. not using it, to help future developers understand the insertion behavior:

 const insertAfter = ({ parent, node, data, target }) => {
   if (!data.id) {
     data.id = utils.guid()
   }

+  // When target is provided, insert after that specific target
+  // When target is not provided, insert after the node specified by node.id
   const targetParentId = target ? target.id : parent.id
packages/canvas/container/src/keyboard.js (2)

106-116: Added support for multi-node clipboard operations

The paste handler now checks for multiple selected nodes in localStorage, enhancing the clipboard functionality to handle copying and pasting multiple nodes at once.

Consider adding error handling for the localStorage operations:

-  const multiSelectedNodes = JSON.parse(localStorage.getItem('multiSelectedNodes') || '[]')
+  let multiSelectedNodes = [];
+  try {
+    multiSelectedNodes = JSON.parse(localStorage.getItem('multiSelectedNodes') || '[]');
+  } catch (error) {
+    console.error('Failed to parse multiSelectedNodes from localStorage:', error);
+  }

124-139: Implemented robust copy logic for multiple node selection

The new handleCopyEvent function intelligently handles both single and multiple selection scenarios, storing selected nodes in localStorage when multiple nodes are selected.

Consider adding error handling for localStorage operations and a clear variable name for better readability:

-  localStorage.setItem('multiSelectedNodes', JSON.stringify([]))
+  try {
+    // Clear previous multi-selection state
+    localStorage.setItem('multiSelectedNodes', JSON.stringify([]))
+  } catch (error) {
+    console.error('Failed to clear multiSelectedNodes in localStorage:', error);
+  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d51ad4 and 6e4878c.

📒 Files selected for processing (3)
  • packages/canvas/DesignCanvas/src/api/useCanvas.js (2 hunks)
  • packages/canvas/container/src/container.js (1 hunks)
  • packages/canvas/container/src/keyboard.js (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: push-check
🔇 Additional comments (5)
packages/canvas/DesignCanvas/src/api/useCanvas.js (3)

320-322: Fixed insertion behavior when reference node is not found

Changed the fallback behavior to insert at the beginning (index 0) when a reference node is not found but a reference ID is provided. This is a better default than appending at the end, as it ensures visibility of newly inserted elements.


327-329: Improved insertion logic for 'before' position

The use of a ternary operator provides clearer conditional logic: insert at the specified index if reference target exists, otherwise insert at the beginning of the children array.


339-343: Enhanced default insertion case with conditional logic

The updated default case now explicitly handles both scenarios - with or without a reference target ID. This makes the insertion behavior more predictable and consistent across the application.

packages/canvas/container/src/keyboard.js (2)

146-147: Updated clipboard event handling for copy operations

The function now uses the new handleCopyEvent handler, which provides better support for multi-selection scenarios.


149-151: Simplified paste event handling

The paste operation now directly calls handleClipboardPaste without additional logic, making the code more maintainable.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/canvas/container/src/utils.js (1)

32-45: Enhanced parsing logic handles both single and multiple nodes.

The improved validation and parsing logic now correctly handles both array and non-array data structures, making the clipboard functionality more robust for multi-node operations.

Consider using optional chaining for cleaner code in the condition check:

- if (Array.isArray(parsedData) && parsedData.every((item) => item && item.componentName)) {
+ if (Array.isArray(parsedData) && parsedData.every((item) => item?.componentName)) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 42-43: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e4878c and 373f4c5.

📒 Files selected for processing (3)
  • packages/canvas/DesignCanvas/src/api/useCanvas.js (2 hunks)
  • packages/canvas/container/src/keyboard.js (2 hunks)
  • packages/canvas/container/src/utils.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/canvas/DesignCanvas/src/api/useCanvas.js
  • packages/canvas/container/src/keyboard.js
🧰 Additional context used
🪛 Biome (1.9.4)
packages/canvas/container/src/utils.js

[error] 42-43: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: push-check
🔇 Additional comments (2)
packages/canvas/container/src/utils.js (2)

16-29: Function parameter and implementation improved to handle node list strings.

The refactoring from accepting a node object to accepting a string representation (nodeStr) aligns with the PR objective to fix multi-node operations. The validation logic ensures robust input handling.


47-62: Graceful error handling with fallback text component.

Instead of returning null on parsing failure, providing a default text component is a more robust approach that prevents potential null reference errors downstream in the application.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/canvas/container/src/keyboard.js (1)

108-114: Consider using optional chaining for safer property access.

To make your code more robust, consider using optional chaining when accessing nested properties:

-  if (node?.componentName && schema?.componentName && allowInsert(getConfigure(schema.componentName), node)) {
+  if (node?.componentName && schema?.componentName && allowInsert(getConfigure(schema?.componentName), node)) {
packages/canvas/container/src/utils.js (2)

40-45: Use optional chaining for safer property access.

According to the static analysis tool, you should use optional chaining when accessing properties that might be undefined:

-if (Array.isArray(parsedData) && parsedData.every((item) => item && item.componentName)) {
+if (Array.isArray(parsedData) && parsedData.every((item) => item && item?.componentName)) {
  return parsedData
-} else if (!Array.isArray(parsedData) && parsedData.componentName) {
+} else if (!Array.isArray(parsedData) && parsedData?.componentName) {
  // 如果解析结果不是数组,将其转为数组
  return [parsedData]
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 42-42: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


36-49: Validate parsed data more thoroughly for security.

Since you're parsing data from the clipboard which can come from external sources, consider adding more thorough validation of the parsed data structure. This could prevent potential security issues if malicious data is pasted.

try {
  const parsedData = JSON.parse(clipText)

  // 如果是数组且每个项都有 componentName
  if (Array.isArray(parsedData) && parsedData.every((item) => item && item.componentName)) {
+    // Additional validation to ensure the structure is safe
+    if (parsedData.some(item => !isValidComponentStructure(item))) {
+      console.warn('Invalid component structure detected in clipboard data')
+      return getDefaultTextComponent(clipText)
+    }
    return parsedData
  } else if (!Array.isArray(parsedData) && parsedData.componentName) {
    // 如果解析结果不是数组,将其转为数组
+    if (!isValidComponentStructure(parsedData)) {
+      console.warn('Invalid component structure detected in clipboard data')
+      return getDefaultTextComponent(clipText)
+    }
    return [parsedData]
  }
} catch (error) {
  // eslint-disable-next-line no-console
  console.warn('剪贴板数据解析失败,转换为文本组件:', error)
}

// Helper function to validate component structure
+function isValidComponentStructure(component) {
+  return (
+    typeof component === 'object' &&
+    typeof component.componentName === 'string' &&
+    (!component.props || typeof component.props === 'object') &&
+    (!component.children || Array.isArray(component.children))
+  )
+}
+
+function getDefaultTextComponent(text) {
+  return [{
+    componentName: 'Text',
+    props: {
+      style: 'display: inline-block;',
+      text: text,
+      className: 'component-base-style'
+    },
+    children: []
+  }]
+}
🧰 Tools
🪛 Biome (1.9.4)

[error] 42-42: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 373f4c5 and e71ffc2.

📒 Files selected for processing (3)
  • packages/canvas/container/src/container.js (0 hunks)
  • packages/canvas/container/src/keyboard.js (2 hunks)
  • packages/canvas/container/src/utils.js (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/canvas/container/src/container.js
🧰 Additional context used
🪛 Biome (1.9.4)
packages/canvas/container/src/utils.js

[error] 42-42: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: push-check
🔇 Additional comments (7)
packages/canvas/container/src/keyboard.js (5)

13-17: Consider organizing imports according to best practices.

Third-party libraries should be imported before local files. Consider reordering your imports to follow this convention:

-import { ref } from 'vue'
-import { useHistory, useCanvas, getMetaApi, META_APP } from '@opentiny/tiny-engine-meta-register'
-import { getCurrent, insertNode, selectNode, POSITION, removeNodeById, allowInsert, getConfigure } from './container'
-import { copyObject } from '../../common'
-import { getClipboardSchema, setClipboardSchema } from './utils'
+import { ref } from 'vue'
+import { useHistory, useCanvas, getMetaApi, META_APP } from '@opentiny/tiny-engine-meta-register'
+import { copyObject } from '../../common'
+import { getCurrent, insertNode, selectNode, POSITION, removeNodeById, allowInsert, getConfigure } from './container'
+import { getClipboardSchema, setClipboardSchema } from './utils'

105-115: Improved multi-node paste handling.

The refactored logic to handle multiple nodes during paste operations is a good improvement. It now properly checks each node against insertion compatibility rules before adding it to the canvas.


117-122: Copy functionality enhanced for multiple nodes.

The new copy handler properly collects all selected nodes and serializes them for clipboard operations. This fixes the multi-node copy issue mentioned in the PR.


130-131: Verify if the schema parameter is needed.

In the previous review, it was noted that there might be a parameter inconsistency. The handleCopyEvent function doesn't use a schema parameter, but it's called with one on line 130. Please verify if this is intentional or if the parameter needs to be handled.


126-127:

❓ Verification inconclusive

Verify clipboard data handling for multiple nodes.

The clipboard data flow has changed significantly. Ensure that getClipboardSchema now properly returns an array that can be handled by handleClipboardPaste.


🏁 Script executed:

#!/bin/bash
# Description: Check the return type of getClipboardSchema implementation
rg -A 10 "getClipboardSchema" --type js packages/canvas/container/src/utils.js

Length of output: 190


Action: Verify Multiple-Node Clipboard Handling

The current implementation of getClipboardSchema simply returns the result of translateStringToSchema, as shown below:

export const getClipboardSchema = (event) => translateStringToSchema(event.clipboardData.getData('text/plain'))

Please confirm that translateStringToSchema correctly returns an array when the clipboard data corresponds to multiple nodes, ensuring that the output is fully compatible with handleClipboardPaste. If it only returns a single node object, consider updating it to support multiple nodes.

packages/canvas/container/src/utils.js (2)

19-29: Improved clipboard schema handling for multi-node operations.

The function now properly handles a string representation of node list instead of a single node object. The validation has been enhanced to check if the input is a non-empty string.


31-63: Enhanced error handling for clipboard data parsing.

The improvements to translateStringToSchema are excellent:

  1. Better input validation
  2. Proper handling of both array and single-object inputs
  3. Fallback to a default text component when parsing fails

These changes make the clipboard functionality more robust.

🧰 Tools
🪛 Biome (1.9.4)

[error] 42-42: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

chilingling
chilingling previously approved these changes Feb 26, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/canvas/container/src/keyboard.js (1)

105-115: Good improvement to the clipboard paste logic.

The updated handleClipboardPaste function now properly handles multiple nodes and uses allowInsert to determine the correct insertion position, which fixes the multi-node paste issue. The empty array check is also improved.

One observation: There's no error handling if insertion fails or if the operation encounters an exception. Consider adding try/catch blocks for robustness.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e71ffc2 and a3e12dd.

📒 Files selected for processing (1)
  • packages/canvas/container/src/keyboard.js (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: push-check
🔇 Additional comments (4)
packages/canvas/container/src/keyboard.js (4)

13-15: Reorder imports to follow convention.

Third-party imports (like Vue) should come before internal imports following the convention mentioned in previous code reviews.

-import { ref } from 'vue'
import { useHistory, useCanvas, getMetaApi, META_APP } from '@opentiny/tiny-engine-meta-register'
+import { ref } from 'vue'
import { getCurrent, insertNode, selectNode, POSITION, removeNodeById, allowInsert, getConfigure } from './container'

126-134: Verify clipboard schema handling.

The changes to use getClipboardSchema and the new helper functions look good, but there's a concern from previous reviews about using localStorage for clipboard operations.

#!/bin/bash
# Check if localStorage is used for clipboard operations and how getClipboardSchema works
echo "Checking getClipboardSchema implementation:"
rg "function getClipboardSchema|const getClipboardSchema" -A 10
echo "\nChecking for localStorage usage in clipboard operations:"
rg "localStorage" -A 3 ./packages/canvas/container/src/

This approach might cause issues in the following scenarios:

  1. When copying something outside the canvas and then pasting in the canvas
  2. When copying in the canvas, then copying something else outside, and then pasting in the canvas

130-130: Schema parameter usage needs verification.

Previous reviews mentioned that line 130 passes a schema parameter, but the receiving function doesn't accept it. Check if this has been addressed in the updated implementation.

For verification:

#!/bin/bash
# Check the definition of handleCopyEvent and if it uses the schema parameter
grep -n "handleCopyEvent" ./packages/canvas/container/src/keyboard.js --include="*.js" -r -A 5

117-122:

✅ Verification successful

Well-implemented copy functionality for multiple nodes.

The new handleCopyEvent function effectively handles copying multiple selected nodes by extracting them from multiSelectedStates, creating a JSON representation, and setting it as clipboard content.

Note that the previous implementation of setClipboardSchema accepted an object, but now it's receiving a string. Ensure that the receiving function has been updated to handle this change.


🏁 Script executed:

#!/bin/bash
# Check how setClipboardSchema is defined and used elsewhere
echo "Checking setClipboardSchema implementation:"
rg "function setClipboardSchema|const setClipboardSchema" -A 3
echo "\nChecking setClipboardSchema usages:"
rg "setClipboardSchema\(" -A 1

Length of output: 866


Copy Functionality Update Verified – Approved

  • The updated handleCopyEvent now converts the node schemas into a JSON string (via JSON.stringify) and passes that string to setClipboardSchema.
  • Verification shows that in packages/canvas/container/src/utils.js, setClipboardSchema now correctly checks that the second argument is a non-empty string.
  • As a note, there remains one instance where setClipboardSchema is called with the result of copyObject(schema). Please double-check that this invocation is intentional and, if needed, update it to maintain consistency with the new string-based interface.

@SonyLeo SonyLeo closed this Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants