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

Python简易文本编辑器实现跨多行光标移动功能求助

Python简易文本编辑器实现跨多行光标移动功能求助

兄弟,我太懂你现在的痛点了!你用input()配合readline的思路,在单行编辑里没问题,但要实现跨多行的光标上下移动,这俩工具就不够用了——毕竟input()本身就是单行输入,readline的上下箭头默认绑定的是历史输入记录,不是行间跳转。

要搞定多行光标移动,咱们得换个思路:用Python标准库的curses,它专门用来做终端下的交互式UI,能直接控制光标位置、处理键盘输入,完美适配你的文本编辑器需求。

下面给你改了一个基于curses的版本,保留了你原来的核心功能(写内容、保存、查看、退出),还实现了上下左右光标移动:

import curses
import os

def main(stdscr):
    # 初始化curses:关闭回显,开启键盘输入,显示光标
    curses.noecho()
    curses.cbreak()
    stdscr.keypad(True)
    curses.curs_set(1)

    # 初始化多行缓冲区和光标位置
    lines = [""]
    cursor_y = 0
    cursor_x = 0
    max_y, max_x = stdscr.getmaxyx()

    # 主循环
    while True:
        # 清屏并绘制内容
        stdscr.clear()
        # 显示操作提示
        stdscr.addstr(0, 0, "简易文本编辑器 | 上下箭头移动行 | 左右箭头移动光标 | Ctrl+S保存 | Ctrl+Q退出")
        # 绘制缓冲区内容(避免超出终端高度)
        for idx, line in enumerate(lines):
            if idx + 1 < max_y:
                stdscr.addstr(idx + 1, 0, line)
        # 定位光标
        stdscr.move(cursor_y + 1, cursor_x)
        stdscr.refresh()

        # 处理键盘输入
        key = stdscr.getch()

        # 可打印字符输入
        if 32 <= key <= 126:
            lines[cursor_y] = lines[cursor_y][:cursor_x] + chr(key) + lines[cursor_y][cursor_x:]
            cursor_x += 1
        # 退格键处理(含跨行合并逻辑)
        elif key == curses.KEY_BACKSPACE or key == 127:
            if cursor_x > 0:
                lines[cursor_y] = lines[cursor_y][:cursor_x-1] + lines[cursor_y][cursor_x:]
                cursor_x -= 1
            elif cursor_y > 0:
                cursor_x = len(lines[cursor_y-1])
                lines[cursor_y-1] += lines[cursor_y]
                del lines[cursor_y]
                cursor_y -= 1
        # 回车键换行
        elif key in [curses.KEY_ENTER, 10, 13]:
            lines.insert(cursor_y + 1, lines[cursor_y][cursor_x:])
            lines[cursor_y] = lines[cursor_y][:cursor_x]
            cursor_y += 1
            cursor_x = 0
        # 上下箭头移动行
        elif key == curses.KEY_UP:
            if cursor_y > 0:
                cursor_y -= 1
                cursor_x = min(cursor_x, len(lines[cursor_y]))
        elif key == curses.KEY_DOWN:
            if cursor_y < len(lines) - 1:
                cursor_y += 1
                cursor_x = min(cursor_x, len(lines[cursor_y]))
        # 左右箭头移动光标(含跨行跳转)
        elif key == curses.KEY_LEFT:
            if cursor_x > 0:
                cursor_x -= 1
            elif cursor_y > 0:
                cursor_y -= 1
                cursor_x = len(lines[cursor_y])
        elif key == curses.KEY_RIGHT:
            if cursor_x < len(lines[cursor_y]):
                cursor_x += 1
            elif cursor_y < len(lines) - 1:
                cursor_y += 1
                cursor_x = 0
        # Ctrl+S保存文件
        elif key == 19:  # ASCII码19对应Ctrl+S
            stdscr.clear()
            stdscr.addstr(0, 0, "请输入文件名: ")
            curses.echo()
            filename = stdscr.getstr(0, 16).decode('utf-8')
            curses.noecho()
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write('\n'.join(lines))
                stdscr.addstr(1, 0, f"文件 {filename} 保存成功!按任意键继续...")
                stdscr.getch()
            except Exception as e:
                stdscr.addstr(1, 0, f"保存失败: {str(e)} 按任意键继续...")
                stdscr.getch()
        # Ctrl+Q退出编辑器
        elif key == 17:  # ASCII码17对应Ctrl+Q
            break

    # 恢复终端原有设置
    curses.nocbreak()
    stdscr.keypad(False)
    curses.echo()
    curses.endwin()

if __name__ == "__main__":
    curses.wrapper(main)

关键功能说明:

  • 光标自由移动:上下箭头在不同行之间跳转,左右箭头支持单行移动,甚至能在行首/行尾自动跨行跳转
  • 完整编辑逻辑:支持输入字符、退格删除、换行拆分,和普通编辑器行为一致
  • 保留核心需求:集成了保存文件、退出功能,操作逻辑更直观
  • 终端适配:自动适配终端窗口大小,不会出现内容溢出问题

为啥放弃原来的input()方案?

因为input()是阻塞式的单行输入,没办法实时监听上下箭头这类全局键盘事件,也没法直接控制终端光标位置。而curses直接接管了终端的输入输出权限,能完全自定义键盘响应和光标行为,这才是做终端文本编辑器的正确思路。

你可以直接运行这段代码试试,有细节需要调整的话再按需修改~

备注:内容来源于stack exchange,提问作者IllTime00qw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:00:30