Сайт

Рабочая область

Рабочая область — это часть приложения, в которой находится пользователь и содержит редактор проекта, команду, мастерскую расширений, главный экран или экран авторизации. sdk.workspace говорит, какая рабочая область активна и какая сущность в ней открыта.

Настройки находятся в этом же пространстве — см. Configuration.

getActive

getActive(): Promise<WorkspaceContext | undefined>

Возвращает текущий контекст или undefined, пока приложение ещё запускается и рабочая область не задана.

const context = await sdk.workspace.getActive()

if (context?.kind === 'project') {
  sdk.window.showInfoMessage(`Работаем над ${context.project?.displayName}`)
}

WorkspaceContext

| Поле | Тип | Когда заполнено | | --- | --- | --- | | kind | WorkspaceKind | Всегда. | | project | ProjectSnapshot | kind равен 'project' и проект открыт. | | team | TeamSnapshot | Команда выбрана — в любом workspace. | | extension | WorkshopExtensionSnapshot | kind равен 'extensionWorkshop' и расширение открыто. |

WorkspaceKind — это 'auth' \| 'project' \| 'team' \| 'extensionWorkshop' \| 'home'. Тот же тип принимает аргумент workspace у window.createStatusbarItem.

Поля-сущности необязательны, и подчиняются двум правилам:

  • project и extension привязаны к своей рабочей области. Если выйти из мастерской в проект, extension исчезает из контекста, хотя мастерская по-прежнему помнит, какое расширение было открыто.
  • ** Поле team не привязано к рабочей области.** Активная команда остаётся выбранной во всех рабочих областях, поэтому поле заполняется всякий раз, когда команда активна. В мастерской расширений это команда, которой принадлежит открытое расширение.

Отсутствующая сущность — не ошибка: рабочая область проекта без загруженного проекта — это просто { kind: 'project' }.

onDidChangeActive

onDidChangeActive: Event<WorkspaceContext>

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

context.subscriptions.push(
  sdk.workspace.onDidChangeActive((workspace) => {
    // перестроить свой UI под новый контекст
  }),
)

Что гарантирует событие:

  • Контекст собран целиком. Каждое событие несёт контекст, собранный за один проход по источникам.
  • Изменения в пределах одного тика объединяются. Уведомление отправляется в конце тика — один раз, с итоговым контекстом. Промежуточные состояния вроде «проект уже очищен, а рабочая область ещё старая» до вашего обработчика не доходят.
  • Состояние ядра уже обновлено. Вызов getActive() внутри обработчика возвращает тот же контекст.
  • Без повторов. Контекст, идентичный предыдущему во всех полях, не вызывает событие.

Чего событие не гарантирует — это количество событий на одно действие пользователя. Объединение работает в пределах одного тика, а сущность, которой нет в кэше, приходит из сети в следующем тике: вход в проект может дать событие только с kind, а затем ещё одно — с project. Необходимо писать обработчик идемпотентным, так как последнее событие соответствует тому, что видит пользователь.

События, пропущенные до активации расширения, не воспроизводятся, необходимо вызвать getActive() в activate, чтобы получить текущее состояние.

Подписки принадлежат вашему расширению. Добавляйте их в context.subscriptions как обычно, но они в любом случае освобождаются при деактивации — после деактивации вашего расширения события в него больше не поступают.

Чего здесь нет

  • Смены workspace из расширения. Неймспейс только на чтение и подписку.
  • Истории. Вы получаете текущий контекст, а не предыдущий workspace.