Xterm.js: API для проверки активности альтернативного экрана

Созданный на 5 февр. 2020  ·  22Комментарии  ·  Источник: xtermjs/xterm.js

Можно ли иметь API, чтобы проверить, показывает ли xterm в настоящее время основной или альтернативный экран?

areapi help wanted typenhancement

Самый полезный комментарий

@jerch Я думаю, что мой первый ответ https://github.com/xtermjs/xterm.js/issues/2694#issuecomment -584537861 немного вводит в заблуждение. @ Tyriar в предложение может решить мою проблему. Я хочу объяснить, почему нам нужен доступ к альтернативному буферу в моем пользовательском случае. Извините за мое плохое выражение лица.

Все 22 Комментарий

@ Евгений, зачем тебе это из любопытства?

У меня есть автоматическое «обнаружение прогресса» в Terminus, которое просматривает процентные строки в выводе терминала. Однако, если текстовый редактор, такой как vi или nano, открыт (обычно в альтернативном режиме экрана) и текст содержит «12%» или аналогичный, он снова и снова перерисовывается приложением, снова вызывая код обнаружения прогресса.

Я хочу просто отключить его, пока активен альтернативный экран

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

Может быть, достаточно добавить isNormalBuffer и isAltBuffer к IBuffer ?

Также было бы неплохо иметь событие типа terminal.onBufferActivate((buffer: IBuffer) => void ) для динамической реакции на изменения буфера.

Возможно, нам также следует воспользоваться этой возможностью для буфера пространства имен, как мы сделали с парсером, что-то вроде этого?

interface buffer {
  normal: IBuffer
  alt: IBuffer
  active: IBuffer
  onDidChangeBuffer: IEvent<IBuffer>
}

@Tyriar Да, звучит хорошо. Так что проверка активности обычного буфера будет выражением типа terminal.buffer.active === terminal.buffer.normal ? Или нам также следует ввести для этого удобный метод либо в интерфейсе buffer либо в интерфейсе IBuffer ?

Думаю, наличие IBuffer.type: 'normal' | 'alt' было бы лучшим из обоих миров?

Небольшое замечание - мы должны позаботиться о том, чтобы предлагать слишком много интроспекции синхронного состояния по простой причине - ppl в конечном итоге будет пытаться делать что-то на основе этого, но в основном игнорирует текущее состояние входного буфера, что может снова изменить ситуацию в любой момент. ( @Tyriar Помните ту проблему,

Или, может быть, нам следует более четко указать это в документе API, который является частью sync / async ...

@jerch Думаю, заметка о write поможет решить эти проблемы. Лучше попытаться решить эту проблему с помощью документации, чем не предлагать ничего подобного.

Мы открыты для PR, возможно, мы захотим немного подправить именование, но я думаю, что основная форма API присутствует.

@Tyriar serialize-addon также нужен способ чтения альтернативного буфера. В противном случае очень сложно реализовать проигрыватель воспроизведения сеанса терминала, даже инструмент совместного использования сеанса терминала, который позволяет любому присоединиться к нему в любое время (я обнаружил, что live share vscode ext уже поддерживает совместное использование терминала, я не знаю, как это работает вместо отправки всего вывода терминала из начало)

@ JavaCS3 Это действительно проблема? Имхо, сериализатор всегда будет получать тот же буфер, который пользователь видит как вывод экрана во время сериализации. Более того, в наши дни приложения обычно используют DECSET 1049, который всегда очищает альтернативный буфер. Таким образом, даже если альтернативный буфер все еще хранит данные, он будет рассматриваться как остаток от предыдущего сеанса альтбуфера.

Imho сериализатору нужно заботиться только об одном буфере в данный момент. Обратите внимание, что реальное воспроизведение невозможно с плагином сериализации, для этого вам нужно будет записать входные данные. (Плагин сериализации - моментальный снимок в заданное время, воспроизведение - восстановление состояния во времени; большая разница).

Редактировать (оффтоп): извините за насмешку над идеей воспроизведения с помощью плагина сериализации, но у меня есть ощущение, что это заблуждение. Плагин сериализации может делать снимки буфера терминала в заданное время. Для плавного воспроизведения этого недостаточно, поскольку вы получаете только отдельные снимки. Что вам нужно для реального воспроизведения, так это «инкрементальные различия» от снимка к снимку. Чтобы сэкономить вам немного работы - вам не нужно самостоятельно вычислять инкрементные различия из двух снимков, они уже есть в красивой сжатой форме - это входные данные с момента первого снимка. Просто сделайте один снимок, затем начните запись входных данных. Обратите внимание, что вам нужно будет сохранить еще несколько внутренних состояний с исходным снимком, чтобы правильно воспроизвести его позже. По крайней мере, вам нужны все параметры, частные флаги DEC, настройки буфера / вкладок, изменение размера перехвата и так далее.

@jerch Для меня terminal._core.buffers.activateNormalBuffer() непосредственно перед запуском аддона сериализации. Было бы лучше, если бы для этого был общедоступный API.

@mofux Итак, вы хотите передать serialize буфер в качестве аргумента? Но разве это не возможно с предложением @Tyriar выше (после расширения сериализации таким образом)? Может я что-то упускаю ...

Изменить (снова немного оффтоп): я думаю, у нас разные идеи, что следует / можно сериализовать в атм. В том виде, в каком она реализована сейчас, сериализация - это «всего лишь» инструмент создания моментальных снимков текущего состояния буфера. Конечно, этого недостаточно для того, чтобы полноценное воспроизведение начиналось в определенное время в терминальной сессии. Возможно, нам следует сначала обсудить, какие более продвинутые функции сериализации необходимы (хотя, возможно, в другом выпуске).

@jerch Основная идея проигрывателя терминального воспроизведения похожа на то, что вы говорите (создайте снимок один за другим и заполните промежуток между снимками с помощью инкрементных различий). Но есть проблема, если время создания снимка находится во время альтернативы, а затем следующие инкрементальные различия содержат DEC 1049 (Use Normal Screen Buffer and restore cursor) . Будет беспорядок, потому что нормальный буфер еще не сериализуется. это моя точка зрения. В противном случае я должен убедиться, что моментальный снимок создан непосредственно перед DECSET 1049 . Но я думаю, было бы полезно, если бы я мог напрямую обращаться как к обычному, так и к альтернативному буферу.

(не по теме)
Я буду использовать asciinema, чтобы записать буфер терминала вместо добавления нового дополнения в xterm.js. Файл записи asciinema похож на

[0.031006, "o", "\u001b]0;mat@mat-mint: ~/Documents/term-tris\u0007\u001b[01;32mmat@mat-mint\u001b[00m:\u001b[01;34m~/Documents/term-tris\u001b[00m$ "]
[0.739447, "o", "s"]
[0.843387, "o", "u"]
[0.939383, "o", "d"]
[1.051685, "o", "o"]
[1.147569, "o", " "]
[1.291866, "o", "p"]
[1.419392, "o", "y"]
[1.578995, "o", "t"]
[1.635077, "o", "h"]
[1.699073, "o", "o"]
[1.810955, "o", "n"]
[1.891268, "o", "3"]
[1.962887, "o", " "]
[2.083119, "o", "m"]
[2.202915, "o", "a"]
[2.315119, "o", "i"]
[2.394943, "o", "n"]
[2.603245, "o", "."]
[2.810757, "o", "p"]
[2.906992, "o", "y"]
[3.034495, "o", "\r\n"]
[3.04091, "o", "[sudo] password for mat: "]
[5.266162, "o", "\r\n"]
[5.369433, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[1;24r\u001b(B\u001b[m\u001b[4l\u001b[?7h\u001b[?1h\u001b="]
[5.402342, "o", "\u001b[39;49m\u001b[?1h\u001b=\u001b[?25l"]
[5.402543, "o", "\u001b[?1000h\u001b[39;49m\u001b[37m\u001b[40m\u001b[H\u001b[2J"]

Цель создания проигрывателя терминала - проигрыватель терминала asciinema написан на ClojureScript, и я думаю, что людям сложно внести свой вклад. Поэтому я решил написать свою версию с xterm.js

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

Но об этом и говорится в предложении

Кажется, что asciinema отслеживает время вывода pty. Yepp, imho единственный способ сделать правильный повтор. Преимущество плагина сериализации здесь будет в том, что вы можете начать воспроизведение с любого снимка, опуская старый вывод pty. Кстати, вы можете довольно легко создать такую ​​временную шкалу схематически:

let recording = false;
const recordedData = [];
function overloadedWrite(chunk, cb) {
  term.write(chunk, () => {
    if (recording) recordedData.push([Date.now(), 'input', chunk]);
    if (cb) cb();
  });
}
// replace term.write invocation with overloaded function
...
// initial snapshot, also activate recording
const initialData = addon.serialize(normal_buffer_as_arg);
// maybe 2nd call with altbuffer (if thats the active atm)
recording = true;
// more states need to be serialized here, like initial DEC private flags
const internalStates = ...
...
// stop recording
recording = false;

// --> final replay from snapshot is initialData + internalStates + recordedData

Это всего лишь приблизительная идея, в ней все еще отсутствуют биты, такие как изменение размера записи. И если вы повторяете моментальный снимок между ними и собираете запись под моментальным снимком, вы в основном получаете «кадры синхронизации», как в кодеках mpeg, которые позже позволяют пропускать / искать.

@jerch Я думаю, что мой первый ответ https://github.com/xtermjs/xterm.js/issues/2694#issuecomment -584537861 немного вводит в заблуждение. @ Tyriar в предложение может решить мою проблему. Я хочу объяснить, почему нам нужен доступ к альтернативному буферу в моем пользовательском случае. Извините за мое плохое выражение лица.

@ JavaCS3 Все хорошо, не надо извиняться. Я думаю, нам следует обсудить дальнейшую сериализацию идей в другом потоке. Похоже, @mofux тоже нуждается в чем-то похожем на реплей (чтение между его строками).

@jerch Я предполагаю, что произошло какое-то недоразумение 🤗 Все, что мне нужно, это чистый способ указать аддону сериализации, какой буфер сериализовать. Я думаю, что API, предложенный @Tyriar , предоставит ему API, необходимый для этого.

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

Это то, чего я хочу в конечном итоге, рассмотрим следующий сценарий:

  1. Открытый код VS
  2. Откройте терминал
  3. Открыть vim
  4. Перезапустить VS Code
  5. Терминал открывается, восстанавливая нормальный и альтернативный буферы.

Я знаю, что в терминале есть другие состояния / режимы, которые могут вызвать проблемы с этим восстановлением, но на данный момент они должны охватывать большинство случаев, и мы всегда можем улучшить при необходимости позже.

Просто придумал мой собственный вариант использования для проверки активности альтернативного буфера: https://github.com/microsoft/vscode/issues/90838

Меня уже можно добиться по этому коду terminal.buffer.active.type или я что-то упускаю?

Меня уже можно добиться по этому коду terminal.buffer.active.type или я что-то упускаю?

Это потому, что # 2713 был объединен

Спасибо за шишку 🙂

Была ли эта страница полезной?
0 / 5 - 0 рейтинги