Skip to content

repl: add support for multiline history - #57400

Merged
nodejs-github-bot merged 13 commits into
nodejs:mainfrom
puskin:repl-multiline-history
Apr 13, 2025
Merged

repl: add support for multiline history#57400
nodejs-github-bot merged 13 commits into
nodejs:mainfrom
puskin:repl-multiline-history

Conversation

@puskin

@puskinpuskin commented Mar 10, 2025

Copy link
Copy Markdown
Contributor

Previously, when navigating the history in the Node.js REPL, multiline commands were displayed line by line, making it difficult to review and edit complete blocks of input.

This PR improves the REPL history behavior by treating multiline commands as a single entry. Now, when scrolling through history, entire blocks of multiline input are displayed together, improving usability and consistency.

Key changes:

  • Adjusted history handling to store and retrieve multiline commands as single entries.
  • Updated navigation logic to properly display multiline inputs.
  • Improved editing experience, allowing users to modify multiline history entries in place.
  • Changed the multiline indicator: from ... to |, to keep the indentation consistent
  • Added the multiline indicator also when editing the history, not only when adding new lines
  • If the last command caused some kind of error, you can now edit the multiline history, and if you remove the error, the history which caused the error will be replaced with the correct one

Important:

This change relies on the fact that I am now formatting new history entries and saving them in the .node_replhistory file in a specific format. While this does not break backward compatibility, it does mean that switching between older and newer versions (i.e., versions without and with this change) will result in multiline history entries not being preserved if they were created with the latest changes.

Impact:

This change significantly enhances the REPL experience for users who frequently enter complex or multiline expressions, making command recall and editing more intuitive.

Testing:

  • Manually tested with various multiline inputs, both on unix and windows systems
  • Verified history navigation behaves as expected with both single-line and multiline commands.

Demos

Before:

before

After:

after

@nodejs-github-botnodejs-github-bot added needs-ci PRs that need a full CI run. readline Issues and PRs related to the built-in readline module. repl Issues and PRs related to the REPL subsystem. labels Mar 10, 2025
@puskin
puskinforce-pushed the repl-multiline-history branch 2 times, most recently from 9137def to 5f9b8f1CompareMarch 12, 2025 10:27
@puskin
puskin marked this pull request as ready for review March 12, 2025 10:27
@codecov

codecovBot commented Mar 12, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.62921% with 6 lines in your changes missing coverage. Please review.

Project coverage is 90.24%. Comparing base (27f98c3) to head (cab0f16).
Report is 555 commits behind head on main.

Files with missing linesPatch %Lines
lib/internal/readline/interface.js95.38%4 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #57400 +/- ##
==========================================
+ Coverage 90.20% 90.24% +0.03% 
==========================================
Files 630 630 Lines 185307 185613 +306 Branches 36269 36400 +131 ==========================================
+ Hits 167162 167507 +345 + Misses 11084 10994 -90 - Partials 7061 7112 +51 
Files with missing linesCoverage Δ
lib/internal/repl/history.js88.46% <100.00%> (+2.19%)⬆️
lib/internal/repl/utils.js96.79% <100.00%> (+0.52%)⬆️
lib/repl.js95.03% <100.00%> (+0.13%)⬆️
lib/internal/readline/interface.js96.76% <95.38%> (-0.19%)⬇️

... and 145 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@puskin
puskinforce-pushed the repl-multiline-history branch from 5f9b8f1 to 8b261aeCompareMarch 12, 2025 12:26
@aduh95

Copy link
Copy Markdown
Contributor

/cc @nodejs/repl

@puskin

Copy link
Copy Markdown
ContributorAuthor

@BridgeAR you, being the requestor, maybe want to give this a shot 😄

@BridgeARBridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a great start!

I did play around with it and I found the following issues:

  1. A history item is now not properly deduplicated anymore if it spans over multiple lines. That is the case with other entries when jumping through the history.
  2. When entering a multiline command that fails to evaluate, it is handled as individual lines. Especially those cases would be great to "correct". For comfort reasons, I would even consider deleting the broken one, if that one is edited and saved successfully right as following command.
  3. Moving up and down while working on a multiline entry feels somewhat off. It is opinionated, but I believe the former history entry should only be shown in case the cursor is at the top line while editing a multiline input. The reason is, that I likely want to finish the input and not change to the former history entry.

I would also change the ... to |. That way the indentation while entering something is identical. I guess we can still look into doing this potentially while going through the entries in the history but at least it is nicer during initial entry.

@puskin
puskinforce-pushed the repl-multiline-history branch 5 times, most recently from a434fe4 to 8e71cdfCompareMarch 18, 2025 15:13
@puskin
puskinforce-pushed the repl-multiline-history branch 2 times, most recently from 897b341 to 3418b3bCompareMarch 19, 2025 21:01
@puskin
puskinforce-pushed the repl-multiline-history branch from 3418b3b to b41273aCompareMarch 21, 2025 16:28
@puskin
puskin requested a review from BridgeARMarch 25, 2025 15:42

@BridgeARBridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is great work! I am looking forward to landing this change!

I left a few comments, mainly to understand some things better.

Comment threadtest/parallel/test-repl-multiline-navigation.js
Comment threadlib/internal/repl/history.js Outdated
Comment threadtest/parallel/test-repl-load-multiline-from-history.js Outdated
Comment threadtest/parallel/test-repl-load-multiline-from-history.js
Comment threadlib/internal/repl/utils.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
Comment threadlib/internal/readline/interface.js Outdated
This will make it consistent when loading the new history format with an old node binary

@BridgeARBridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! Thank you for the great work! 🥳

@BridgeARBridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 12, 2025
@github-actionsgithub-actionsBot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 12, 2025
@nodejs-github-bot

nodejs-github-bot commented Apr 12, 2025

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@BridgeARBridgeAR added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 13, 2025
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@BridgeARBridgeAR added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Apr 13, 2025
@nodejs-github-botnodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 13, 2025
@nodejs-github-bot
nodejs-github-bot merged commit 4a4aa58 into nodejs:mainApr 13, 2025
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in 4a4aa58

@lpinca

Copy link
Copy Markdown
Member

It seems that test/parallel/test-repl-multiline-navigation is flaky. See https://ci.nodejs.org/job/node-test-commit-aix/56805/nodes=aix72-ppc64/testReport/junit/(root)/parallel/test_repl_multiline_navigation/

---
duration_ms: 324.926
exitcode: 1
severity: fail
stack: |-
node:assert:95
throw new AssertionError(obj);
^
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
2 !== 1
at /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-ppc64/test/parallel/test-repl-multiline-navigation.js:132:12
at /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-ppc64/test/common/index.js:400:17
at /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-ppc64/test/common/index.js:435:15
at REPLServer.<anonymous> (node:internal/repl/history:120:9)
at Object.onceWrapper (node:events:621:28)
at REPLServer.emit (node:events:507:28)
at REPLServer.emit (node:domain:489:12)
at onwritten (node:internal/repl/history:156:14)
at FSReqCallback.wrapper [as oncomplete] (node:fs:803:5)
at FSReqCallback.callbackTrampoline (node:internal/async_hooks:130:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 2,
expected: 1,
operator: 'strictEqual'
}
Node.js v24.0.0-pre
...

Can you take a look?

@puskin

Copy link
Copy Markdown
ContributorAuthor

@lpinca thanks for the report!
It should get fixed here: #57874 😄

RafaelGSS pushed a commit that referenced this pull request May 1, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
RafaelGSS pushed a commit that referenced this pull request May 2, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
RafaelGSS pushed a commit that referenced this pull request May 14, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
aduh95 pushed a commit that referenced this pull request May 16, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
aduh95 pushed a commit that referenced this pull request May 17, 2025
PR-URL: #57400
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
@aduh95aduh95 added the backport-requested-v22.x PRs awaiting manual backport to the v22.x-staging branch. label May 18, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.backport-requested-v22.xPRs awaiting manual backport to the v22.x-staging branch.commit-queue-squashAdd this label to instruct the Commit Queue to squash all the PR commits into the first one.needs-ciPRs that need a full CI run.notable-changePRs with changes that should be highlighted in changelogs.readlineIssues and PRs related to the built-in readline module.replIssues and PRs related to the REPL subsystem.semver-minorPRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@puskin@aduh95@nodejs-github-bot@ljharb@BridgeAR@lpinca