4

Скажем, я разделил окно на 2 панели, правая имеет ширину 20 ячеек. Но когда я изменяю размер внешнего эмулятора терминала, ширина панели изменяется.

Есть ли способ это исправить? Потому что я хочу отображать информацию, которая отформатирована под 20 ячеек

2 ответа2

4

Насколько я могу судить, tmux не имеет никаких настроек для фиксации ширины до минимального значения, только до максимального значения. Это связано с тем, что размеры окон терминала могут быть меньше минимального значения tmux, а tmux может не иметь подходящего способа справиться с этим.

При этом, если у вас открыты другие панели tmux, вы можете добавить небольшой скрипт в PS1 (PS1='$(resizePane $id)other-stuff') или PROMPT_COMMAND, чтобы постоянно изменять размер информационной панели, которую вы хотите придерживайтесь ширины 20c, так как вы используете другие панели в tmux. По сути, 1) вы можете открыть программу, 2) изменить размер терминала, 3) перейти на другую панель, 4) набрать Enter и blam, размер панели будет изменен.

Вы должны посмотреть на страницы руководства для

resize-pane [-DLRU] [-t target-pane] [adjustment]

Если вы находитесь на нужной панели, все, что нужно сделать, это уменьшить ширину слева -L или справа -R на x символов, необходимых для достижения 20. По сути, если панель находится напротив стены выше, чем панель, используйте ее направление для сжатия, а противоположное - для увеличения. Если моя панель находится рядом с правой стеной, используйте -R, чтобы уменьшить ширину, и -L, чтобы увеличить ее.

Чтобы получить правильное количество символов, вам нужно знать текущую ширину панели, которую можно найти вместе с идентификатором панели, если вы наберете

tmux list-panes

Я пока не уверен, как определить номер панели, кроме Prefix+q или ввода

tmux display-panes

Это даст нам номер идентификатора всех панелей в текущем окне. Если мы знаем id # ($ id), предполагая, что он у правой стены, мы можем изменить размер панели до 20 символов в ширину:

paneWidths=$(tmux list-panes | awk '{print $2}' | cut -c 2- | cut -f 1 -d'x')
currentWidth=$(echo $paneWidths | sed $id'q;d')
resizeNum=$(expr $currentWidth - 20)

tmux resize-pane -R -t $id $resizeNum

Обратите внимание, что resizeNum не может быть отрицательным. Если оно отрицательное, используйте другую сторону, чтобы изменить размер до абсолютного значения resizeNum (это можно автоматизировать, но я оставлю это на ваше усмотрение). Кроме того, если вы включите это в код своей программы, вы можете пренебречь частью «-t $ id», но я не знаю способа автоматизировать поиск $ id из вашей программы.

Также может быть полезно взглянуть на tmux setw main-pane-width tmux setw other-pane-width , который установит конкретную ширину панели, если вы перезагрузите новый формат листов. Для циклического форматирования используйте Prefix+space

Надеюсь это поможет!

--- отредактировано, чтобы добавить дополнительную информацию об автоматизации ---

Моя предыдущая мысль была для вас - перейти на новую панель и запустить PS1="$(resizePane $id)${PS1}" а затем нажать ENTER на другой панели, чтобы вы могли продолжить работу на новой панели изменения размера, но Я рассмотрел новый вариант, который может работать для вас ...

Я переосмыслил эту идею с момента первоначальной публикации и думаю, что она может быть разумно автоматизирована, если запущенная программа имеет цикл, который может отправлять команды оболочки. Это потому, что мы можем запустить программу, по существу разделив окно. Вот пример того, что я имею в виду. Следующий код

  1. Пользователь запускает runCodeSplit.sh , который
  2. разбивает новую панель по горизонтали (ширина 20c) справа от последней панели и запускает test.sh
  3. Введите цикл
  4. проверяет текущий размер панели и пытается изменить ее размер
  5. Спит 10 секунд (но вы можете изменить это, чтобы сделать все, что вы хотите)
  6. повторяется 3 и 4 раза 10, затем выходит

runCodeSplit.sh:

#!/bin/bash
# runCodeSplit.sh

paneID=$(tmux list-panes | wc -l)
echo "pane: $paneID"
echo $(expr $paneID - 1)

# now, open a new pane and run the func
tmux split-window -h -l 20 -t $(expr $paneID - 1 ) "~/test.sh $paneID"

test.sh:

#!/bin/bash
# test.sh
if [[ $# -lt 1 ]] ; then 
    echo "please provide the pane-number" 
    exit 
fi
paneID=$1
i=0
while [[ i -lt 10 ]] ; do
    # find the current width and resize it at every loop
    width=$(tmux list-panes | awk '{print $2}' | cut -c 2- | cut -f 1 -d'x' | sed $(expr $paneID + 1)'q;d')
    resizeNum=$(expr $width - 20)
    echo "$paneID : w $width     r $resizeNum"

    if [[ $resizeNum -gt 0 ]] ; then
        tmux resize-pane -R -t $paneID $resizeNum
    elif [[ $resizeNum -lt 0 ]] ; then
        tmux resize-pane -L -t $paneID $(expr 0 - $resizeNum)
    fi 

    #now, we can do stuff ... 
    let i++
    echo "i= $i / 10"
    sleep 10
done
read -p "Press any key to close this pane ... " -n1 -s

ПРИМЕЧАНИЕ: К сожалению, как я реализовал выше, вы должны запускать его только один раз для каждого окна tmux. Проблема в том, что каждый раз, когда вы запускаете его, они собираются рядом друг с другом, что, в свою очередь, приводит к тому, что они конкурируют за место (одно сокращает другое, чтобы расширяться, и наоборот). Возможно, вы сможете обойти эту проблему, но я оставлю это на ваше усмотрение, чтобы выяснить.

2

Я выложу свой сорт, так как он никому не повредит, и, возможно, подойдет кому-то лучше как есть

Я использую его для изменения размера панели в сеансе irssi внутри tmux, который читает вывод из скрипта nicklist.pl . Размер панели часто изменяется, когда я присоединяюсь к разным терминалам, и для правильной работы FIFO необходимо иметь ширину> 20 столбцов (и нет необходимости иметь ее шире, крадя пространство на экране).

Игнорируйте сложный расчет CURRENT_PANE_WIDTH и используйте вместо него grep+sed, если хотите. Текущий был в основном экспериментом, чтобы сохранить скрипт полностью в оболочке (за исключением вызовов tmux, конечно). Скорее всего, это быстрее, что может быть интересно для автоматизации, где скрипт часто запускается (хотя я сейчас запускаю его как специальный вызов).

#!/bin/sh
TMUX="/usr/bin/tmux"
TMUX_SESSION="irssi"
TMUX_WINDOW="0"
TMUX_WINDOW_PANE="1"
DESIRED_PANE_WIDTH="20"

error()
{
    printf '%s: error: %s\n' "${0##*/}" "${1}" 1>&2
    exit ${2}
}

# Find with grep and sed. More readable and easier to modify.
#CURRENT_PANE_WIDTH="$(${TMUX} list-panes -t "${TMUX_SESSION}:0 | grep "^${TMUX_WINDOW_PANE}: " | sed 's/^'"${TMUX_WINDOW_PANE}"': \[\([^x]\+\).*/\1/')"

# Find with shell expansion. Because it can be done!
CURRENT_PANE_WIDTH=$(${TMUX} list-panes -t "${TMUX_SESSION}:${TMUX_WINDOW}" |\
while read line; do
    PANE_MATCH="${line#${TMUX_WINDOW_PANE}:\ \[}"
    if [ "${line}" != "${PANE_MATCH}" ]; then
        CURRENT_PANE_WIDTH="${PANE_MATCH%%x*}"
        printf "${PANE_MATCH%%x*}"
        break;
    fi
done)

if [ -z "${CURRENT_PANE_WIDTH}" ]; then
    error 'no matching pane found.' 1
fi

if ! [ "${CURRENT_PANE_WIDTH}" -eq "${CURRENT_PANE_WIDTH}" ]; then
    error 'could not get integer width.' 1
elif ! [ "${CURRENT_PANE_WIDTH}" -eq "${DESIRED_PANE_WIDTH}" ]; then
    RESIZE_NUMBER=$((${CURRENT_PANE_WIDTH} - ${DESIRED_PANE_WIDTH}))
    if [ ${RESIZE_NUMBER} -ge 0 ]; then
        DIRECTION="R"
    else
        DIRECTION="L"
        RESIZE_NUMBER=$((-${RESIZE_NUMBER}))
    fi

    ${TMUX} resize-pane -t "${TMUX_SESSION}:${TMUX_WINDOW}" -${DIRECTION} ${RESIZE_NUMBER}
fi

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .