Як запустити XTerm із запиту внизу?


12

При запуску XTerm рядок починається з першого рядка терміналу. Під час виконання команд рядок рухається вниз, поки не досягне нижньої частини, і відтоді він залишається там (навіть не Shift- Page Downабо миша може це змінити). Замість того, щоб почати термін експлуатації терміналу бути "спеціальним", підказка завжди повинна знаходитися в нижній частині терміналу. Зверніть увагу, що у мене є багаторядковий запит .

Звичайно, він повинен працювати інакше (коли можна змінити розмір, прокручувати, не мати зайвих нових рядків у виводі та таємно не зникати), тому PROMPT_COMMAND='echo;echo;...'подібне чи подібне не є варіантом. Рішення в ідеалі не повинно бути специфічним для оболонки.

Edit: поточне рішення , при роботі в простих випадках, є кілька питань:

  • Це Баш специфічно . Ідеальне рішення повинно бути переносним для інших оболонок.
  • Він не працює, якщо інші процеси змінюютьсяPS1 . Одним з прикладів є virtualenv, який додає (virtualenv)в початку з PS1, який потім завжди зникає трохи вище складки.
  • Ctrl- lтепер видаляється остання сторінка історії.

Чи є спосіб уникнути цих проблем, окрім розробки XTerm?


Якось нам потрібно ввести порожні символи в буфер прокрутки Xterm.
SHW

3
Насправді, підказку можна легко повернути вгору в будь-який час, виконавши clearкоманду.
werediver

@SHW Я сподівався, що це налаштування для цього, а не злому. Термінальні хаки мають тенденцію вводити дуже тонкі помилки в мій досвід.
l0b0

@werediver Але я ніколи не хочу, щоб це було на вершині.
l0b0

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 не буде проти, що я відредагував його / її відповідь.
Stéphane Chazelas

'\[$(tput cup "$LINES")\]' працює прекрасно . Спасибі!
l0b0

Виникає проблема з tput: Здається, скидання $exit_code. Виправлено за допомогою \[\e[$LINES;1H\].
l0b0

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після цих змін, щоб переконатися, що вони виглядають так, як вам потрібно. Але в питанні недостатньо деталей, щоб вказати, куди вносити зміни.

І нарешті: поведінка для заповнення вкладки не поєднується з подібними змінами через припущення Баша.


Що ви маєте на увазі під "поведінкою щодо заповнення вкладки, не поєднується з подібними змінами"?
l0b0

Я думаю, ти маєш на увазі PS1="${TPUT_END} myprompt: "або навітьPS1="${TPUT_END}${PS1}"
l0b0

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