Windows Terminal最新更新功能解析与Golang开发适配指南

Windows Terminal最新更新功能解析与Golang开发适配指南 如何仅删除Windows终端显示内容中的最后一行?

1 回复

更多关于Windows Terminal最新更新功能解析与Golang开发适配指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Windows Terminal中删除最后一行显示内容,可以通过Golang调用Windows API实现。以下是使用kernel32console相关函数的具体实现:

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

var (
    kernel32 = syscall.NewLazyDLL("kernel32.dll")
    getStdHandle = kernel32.NewProc("GetStdHandle")
    setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
    getConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
)

type coord struct {
    X int16
    Y int16
}

type smallRect struct {
    Left   int16
    Top    int16
    Right  int16
    Bottom int16
}

type consoleScreenBufferInfo struct {
    Size              coord
    CursorPosition    coord
    Attributes        uint16
    Window            smallRect
    MaximumWindowSize coord
}

func main() {
    // 获取标准输出句柄
    hConsoleOutput, _, _ := getStdHandle.Call(uintptr(syscall.STD_OUTPUT_HANDLE))
    
    // 获取控制台屏幕缓冲区信息
    var csbi consoleScreenBufferInfo
    getConsoleScreenBufferInfo.Call(hConsoleOutput, uintptr(unsafe.Pointer(&csbi)))
    
    // 计算新光标位置(上移一行)
    newCursorPos := coord{
        X: 0,
        Y: csbi.CursorPosition.Y - 1,
    }
    
    // 如果光标已在第一行,则不清除
    if newCursorPos.Y < 0 {
        newCursorPos.Y = 0
    }
    
    // 设置光标位置
    setConsoleCursorPosition.Call(
        hConsoleOutput,
        uintptr(uint32(newCursorPos.Y)<<16|uint32(newCursorPos.X)),
    )
    
    // 清除当前行
    fmt.Print("\033[2K")
}

更简洁的ANSI转义序列方法:

package main

import (
    "fmt"
    "strings"
)

func clearLastLine() {
    // 光标上移一行
    fmt.Print("\033[1A")
    // 清除整行
    fmt.Print("\033[2K")
    // 光标回到行首
    fmt.Print("\r")
}

func main() {
    fmt.Println("第一行内容")
    fmt.Println("第二行内容")
    fmt.Println("第三行内容")
    
    // 删除最后一行
    clearLastLine()
    
    // 继续输出新内容
    fmt.Println("新的第三行内容")
}

如果需要处理多行文本并删除最后一行:

func deleteLastLineFromString(output string) string {
    lines := strings.Split(output, "\n")
    if len(lines) > 1 {
        lines = lines[:len(lines)-1]
    }
    return strings.Join(lines, "\n")
}

func main() {
    output := `第一行内容
第二行内容
第三行内容`
    
    fmt.Println("原始输出:")
    fmt.Println(output)
    
    fmt.Println("\n删除最后一行后:")
    fmt.Println(deleteLastLineFromString(output))
}

对于需要实时更新终端显示的场景:

package main

import (
    "fmt"
    "time"
)

type TerminalWriter struct {
    lineCount int
}

func (tw *TerminalWriter) WriteLine(text string) {
    // 清除之前的所有行
    for i := 0; i < tw.lineCount; i++ {
        fmt.Print("\033[1A\033[2K")
    }
    
    // 输出新内容
    fmt.Println(text)
    tw.lineCount = 1
}

func (tw *TerminalWriter) UpdateLastLine(text string) {
    if tw.lineCount > 0 {
        fmt.Print("\033[1A\033[2K")
    }
    fmt.Println(text)
}

func main() {
    writer := &TerminalWriter{}
    
    for i := 1; i <= 5; i++ {
        writer.WriteLine(fmt.Sprintf("进度: %d/5", i))
        time.Sleep(500 * time.Millisecond)
    }
    
    // 删除最后一行并更新
    writer.UpdateLastLine("任务完成")
}

这些示例展示了在Windows Terminal中删除最后一行的不同方法,包括直接操作控制台光标和使用ANSI转义序列。选择哪种方法取决于具体的使用场景和需求。

回到顶部