Как запустить XTerm с подсказкой внизу?


12

При запуске XTerm приглашение запускается в первой строке терминала. При запуске команд подсказка перемещается вниз до тех пор, пока не достигнет дна, и с тех пор она остается там (даже не Shift- Page Downили мышь может изменить это). Вместо того, чтобы начало срока службы терминала было «специальным», подсказка всегда должна быть в нижней части терминала. Обратите внимание, что у меня есть многострочная подсказка .

Конечно, в противном случае он должен работать как прежде (изменяемый размер, прокручиваемый, без лишних переводов строки в выходных данных и без таинственного исчезновения выходных данных), поэтому PROMPT_COMMAND='echo;echo;...'аналогичный вариант не подходит. Решение в идеале не должно быть специфичным для оболочки.

Edit: текущее решение , при работе в простых случаях, есть несколько вопросов:

  • Это специфично для Bash . Идеальное решение должно быть переносимым на другие оболочки.
  • Это не выполняется , если другие процессы измененияPS1 . Одним из примеров является virtualenv, который добавляет (virtualenv)в начале из PS1, который затем всегда исчезает чуть выше складки.
  • Ctrl- lтеперь удаляет последнюю страницу истории.

Есть ли способ избежать этих проблем, кроме разветвления XTerm?


Каким-то образом нам нужно ввести пустые символы в буфер полосы прокрутки Xterm.
ШВ

3
На самом деле, запрос может быть легко перемещен обратно в начало в любое время, выполнив clearкоманду.
Werediver

@SHW Я надеялся, что для этого есть настройка, а не взлом. Терминальные хаки имеют тенденцию вводить очень тонкие ошибки в моем опыте.
10

@edediver Но я никогда не хочу, чтобы это было на вершине.
10

1
Поскольку только оболочка знает, когда она выводит подсказку, любое решение должно быть в контексте оболочки. Даже разветвление XTerm не поможет, потому что XTerm не знает, является ли то, что его просят вывести, подсказкой или нет. Для терминала приглашение оболочки - это просто другая последовательность символов, не отличающаяся от любой другой последовательности символов, которую она может получить.
celtschk

Ответы:


11

При использовании bash, следующее должно сделать трюк:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

Или (менее эффективно, поскольку он запускает одну tputкоманду перед каждым приглашением, но работает после изменения размера окна терминала):

PS1='\[$(tput cup "$LINES")\]'$PS1

Чтобы предотвратить tputизменение кода выхода, вы можете явно сохранить и сбросить его:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

Обратите внимание, что переменная retvalявляется локальной; это не влияет на retvalпеременную, которую вы могли бы определить в оболочке.

Поскольку cupвозможности большинства терминалов одинаковы \e[y;xH, вы также можете жестко закодировать их:

PS1='\[\e[$LINES;1H\]'$PS1

Если вы хотите, чтобы это было безопасно от последующего сброса PS1, вы также можете использовать PROMPT_COMMANDпеременную. Если установлен, он запускается как команда перед выводом приглашения. Таким образом, эффект также может быть достигнут

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

Конечно, хотя сброс PS1не повлияет на это, некоторые другие программы также могут измениться PROMPT_COMMAND.


Чем tputотличаются многие echoкоманды? (Спрашивая из любопытства)
SHW

@ l0b0, вероятно, не заслуживает отдельного ответа. Я надеюсь, что celtschk не возражает, я отредактировал его / ее ответ.
Стефан Шазелас

'\[$(tput cup "$LINES")\]' работает прекрасно . Благодарность!
10

Существует проблема с tput: Кажется, для сброса $exit_code. Исправлено с помощью \[\e[$LINES;1H\].
10

1
@ l0b0: я добавил версию, в tputкоторой сохраняется код завершения.
celtschk

4

В качестве небольшого упрощения к предыдущему ответу, мне было проще просто запустить:

tput cup $LINES

в начале .bashrcили .zshrc. Это просто делает работу.

Плюсы:

  • он печатается только один раз, когда вы запускаете вашу оболочку

Минусы:

  • при очистке экрана с ^ L, не печатает и наложение clearна clear; tput ...не помогает;
  • подсказка перемещается в другое место при изменении размера терминала

2

Использование ответов $LINESизлишне непереносимо. Как и в случае resize, вы можете просто попросить xtermустановить позицию на произвольно большой номер строки, например,

tput cup 9999 0

(при условии, что у вас есть окно меньше 10 тысяч строк, без учета прокрутки ).

Поскольку строка не изменится как побочный эффект изменения размера окна, вы можете вычислить это один раз и вставить в строку подсказки как константу, например:

TPUT_END=$(tput cup 9999 0)

и позже

PS1="${TPUT_END} myprompt: "

в соответствии с вашими предпочтениями.

Что касается других процессов, изменяющих PS1: вам придется пересчитать PS1после этих изменений, чтобы убедиться, что он выглядит так, как вы хотите. Но в вопросе недостаточно подробностей, чтобы указать, где внести изменения.

И наконец: поведение для завершения табуляции не согласуется с такого рода изменениями из-за предположений bash.


Что вы подразумеваете под "поведением о завершении табуляции не совпадает с такого рода изменениями"?
l0b0

Я думаю, что вы имеете в виду PS1="${TPUT_END} myprompt: ", или дажеPS1="${TPUT_END}${PS1}"
l0b0

Для последнего - правильно (опечатка от размышлений о make-файлах). Для первого я имею в виду, что редактирование команд bash зависит от возможности перепечатать строку (с подсказкой), и что вы можете получить странное поведение, когда это сочетается с прокруткой из-за завершения команды.
Томас Дики
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.