You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现命令行中输入内容显示在输入行上方的聊天式输出?

Hey there! Great question about building that chat-style command-line output. Your current approach works, but there are a few more elegant ways to get that exact behavior where your input shows up above the prompt. Let's break down three solid alternatives:


1. ANSI Escape Sequences (Smooth, Dynamic Updates)

This is my go-to method for clean, flicker-free CLI interfaces. ANSI escape codes let you control the cursor position directly, so you can insert new messages above the separator without redrawing the entire screen.

Here's how to implement it:

username = "Tim"

def print_chat_message(message)
  puts message
end

# Initialize the interface
puts "-" * 30
print "What do you want to say? > "

loop do
  input = gets.chomp
  break if input.downcase == "exit" # Add a way to quit

  # Step 1: Clear the current prompt line to avoid leftover text
  print "\e[K"
  # Step 2: Move cursor up 1 line to the separator
  print "\e[1A"
  # Step 3: Jump to the start of that line
  print "\e[0G"
  # Step 4: Print the new chat message above the separator
  print_chat_message("#{username}: #{input}")
  # Step 5: Re-print the separator and prompt
  puts "-" * 30
  print "What do you want to say? > "
end

How it works:

  • \e[K: Clears the current line (so old prompt text doesn't linger)
  • \e[1A: Moves the cursor up 1 line to the separator
  • \e[0G: Jumps to the start of the line, letting us print the new message above the separator
  • We re-print the separator and prompt to reset the interface, with the cursor back in the input position

2. Clear and Redraw the Screen (Simple, No Fancy Codes)

If you don't mind a slight screen flicker, this method is dead simple. We maintain a history of chat messages, then clear the entire screen and re-draw everything each time the user sends a message.

username = "Tim"
chat_history = []

def clear_terminal
  # Works on macOS/Linux and Windows
  system("clear") || system("cls")
end

loop do
  # Clear the screen first
  clear_terminal
  # Print all past messages
  chat_history.each { |msg| puts msg }
  # Print the separator
  puts "-" * 30
  # Get user input
  print "What do you want to say? > "
  input = gets.chomp
  break if input.downcase == "exit"
  # Add the new message to history
  chat_history << "#{username}: #{input}"
end

Pros & Cons:

  • Pros: Super easy to write and debug, no need to learn ANSI codes
  • Cons: Screen flickers each time you send a message, which might be distracting for longer chats

3. Use Ruby's Readline Library (Advanced CLI Features)

Ruby's built-in readline library adds powerful features like input history (press up arrow to see past messages) and line editing, while still letting you control the output layout.

require 'readline'

username = "Tim"
chat_history = []

# Set the default prompt
Readline.prompt = "What do you want to say? > "

loop do
  # Read input with history support (the `true` saves it to history)
  input = Readline.readline(nil, true)
  break if input.nil? || input.downcase == "exit"

  # Add the message to our chat history
  chat_history << "#{username}: #{input}"

  # Clear and re-draw the interface
  system("clear") || system("cls")
  chat_history.each { |msg| puts msg }
  puts "-" * 30
  # Reset the prompt after clearing the screen
  Readline.prompt = "What do you want to say? > "
end

Why use this?

  • Built-in input history makes it easy for users to re-send or edit past messages
  • Handles line editing (like using left/right arrows to fix typos) automatically
  • More stable than manual gets for complex CLI interactions

Each method has its sweet spot: ANSI sequences give you the smoothest experience, clear-redraw is perfect for quick prototypes, and readline is ideal if you want to build a more polished CLI tool.

内容的提问来源于stack exchange,提问作者Tim Tenb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:43:29