ล้างบรรทัดพรอมต์เก่าในทุบตีเพื่อประหยัดพื้นที่เลื่อน


11

ชุดรูปแบบเทอร์มินัลของฉันเคยเป็นเช่นนี้

ขั้วพวกเขาก่อน

แต่ฉันคิดว่าพรอมต์เสียพื้นที่มากมาย และต่อมาฉันก็มีความคิดว่าฉันสามารถทำความสะอาดพรอมต์ทุกครั้งที่ฉันมีคำสั่ง ฉันใช้ทุบตีวิธีหนึ่งคือใช้preexec_invoke_execฟังก์ชั่น

ฉันใช้คำสั่งต่อไปนี้เพื่อทำความสะอาดตัวอักษรพรอมต์ล่าสุด:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

เพื่อให้เครื่องนั้นสะอาดมากเช่นนี้

ป้อนคำอธิบายรูปภาพที่นี่

แต่ตอนนี้ปัญหาของฉันจะมีปัญหาถ้าผมต้องการที่จะใช้คำสั่งหลายในหนึ่งบรรทัดfor i in ...กล่าวว่าเมื่อผมใช้

นี่คือเวอร์ชั่นเต็มของฟังก์ชั่นใน. bashrc ของฉัน

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
}
trap 'preexec_invoke_exec' DEBUG

เคล็ดลับ Glyph Lefkowitz zsh - ดี!

2
ทางออกที่ง่ายเริ่มต้นด้วยzsh...
Gilles 'หยุดความชั่วร้าย'

ฉันคิดถึงคำถามของคุณอยู่ในนั้น ...
เดวิด Hoelzer

@DavidHoelzer เอาละถ้าคุณfor i in $(seq 1 10); do ls; doneใช้ฟังก์ชั่นของเขาเอาต์พุตของคำสั่งวนซ้ำจะถูก "กลืน" เพื่อพูด ดังนั้น OP จึงต้องการที่จะทำให้พฤติกรรมนั้นสะอาดในขณะที่เปิดใช้งานพรอมต์นั้น เหตุผลที่ฉันสนับสนุนสิ่งนี้คือความสนใจในการรับรู้ในเชลล์การใช้งานข้อเสนอแนะและการพกพา ลิงก์ที่ฉันใส่ไว้ในความคิดเห็นก่อนหน้าของฉันนำไปสู่การโพสต์ใน superuser - พวกเขาประสบปัญหาในการระบุตัวอย่างนี้ดังนั้นมันจึงเป็นต้นแบบที่เลียนแบบฟังก์ชัน zsh ดั้งเดิม (ซึ่งฉันคิดว่าน่าสนใจ) ในรูปแบบของฟังก์ชันดัก ที่นี่

คำตอบ:


3

ก่อนอื่นpreexec_invoke_execจะต้องมีการแก้ไขเพื่อป้องกันการประหารชีวิตหลายpreexecครั้ง รวมทั้งแก้ไขpreexecเพื่อพิจารณาจำนวนบรรทัดที่แท้จริงใน$PS1:

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
    do             
        echo -ne "\e[1A\e[K"
    done
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"
}

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    DONTCLEANPROMPT=x
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"
}

trap 'preexec_invoke_exec' DEBUG

PROMPT_COMMAND='unset DONTCLEANPROMPT'

ในเพื่อpreexecที่จะทำงานอีกครั้งจะต้องมีทั้งไม่มีการตั้งค่าหรือตั้งค่าDONTCLEANPROMPT ''สิ่งนี้ทำด้วยPROMPT_COMMANDซึ่งจะทำงานก่อนที่จะมีพรอมต์หลักออกมา ดังนั้นpreexecจะเรียกใช้เพียงครั้งเดียวและครั้งเดียวเท่านั้นสำหรับทุกบรรทัดคำสั่ง


ทางออกของคุณแก้ปัญหาด้วยการforวนซ้ำ! ขอขอบคุณ! มีความไม่สะดวกเพิ่มเติม จะเกิดอะไรขึ้นถ้าคุณทำlsตามคำสั่งและคุณมีเอาต์พุตจากนั้นคุณก็ทำอีกlsอันคุณจะเห็นว่าบรรทัดสุดท้ายของเอาต์พุตก่อนหน้าจะถูกลบ ... คุณมีความคิดว่าจะแก้ไขได้อย่างไร?

1
คุณอาจใช้พรอมต์โดยใช้เพียงบรรทัดเดียว เปลี่ยนเสียงสะท้อนแรกในprexecการพิมพ์"\033[1A\033[K\033[31;1m$ \033[0m"ซึ่งเป็นเพียงหนึ่ง\033[1A\033[K(เลื่อน 1 บรรทัดขึ้นลบไปจนจบบรรทัด) แทนที่จะเป็นสองบรรทัด
Adaephon

ไร้ที่ติ! ขอบคุณมากสำหรับวิธีการแก้ปัญหาของคุณและสละเวลาในการอธิบาย สิ่งนี้จะช่วยแก้ปัญหาของ OP และแก้ไขข้อบกพร่องให้ดียิ่งขึ้น ทำให้ใช้งานได้สำหรับทุกคน! ไชโย!
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.