1// Copyright 2024 The Pigweed Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may not 4// use this file except in compliance with the License. You may obtain a copy of 5// the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations under 13// the License. 14 15import { EventEmitter } from 'vscode'; 16 17import { Disposer } from './disposables'; 18 19import { 20 OK, 21 RefreshCallback, 22 RefreshManager, 23 RefreshStatus, 24} from './refreshManager'; 25 26/** Event emitted on extension load. */ 27export const didInit = new EventEmitter<void>(); 28 29/** Event emitted when the code analysis target is changed. */ 30export const didChangeTarget = new EventEmitter<string>(); 31 32/** Event emitted when the active files cache has been updated. */ 33export const didUpdateActiveFilesCache = new EventEmitter<void>(); 34 35/** Event emitted whenever the `clangd` configuration is changed. */ 36export const didChangeClangdConfig = new EventEmitter<void>(); 37 38/** Event emitted when the refresh manager state changes. */ 39export const didChangeRefreshStatus = new EventEmitter<RefreshStatus>(); 40 41/** 42 * Helper for subscribing to events. 43 * 44 * This lets you register the event callback and add the resulting handler to 45 * a disposer in one call. 46 */ 47export function subscribe<T>( 48 event: EventEmitter<T>, 49 cb: (data: T) => void, 50 disposer: Disposer, 51): void { 52 disposer.add(event.event(cb)); 53} 54 55/** 56 * Helper for linking refresh manager state changes to VSC events. 57 * 58 * Given a refresh manager state, it returns a tuple containing a refresh 59 * callback that fires the event, and the same status you provided. This just 60 * makes it easier to spread those arguments to the refresh manager callback 61 * register function. 62 */ 63const fireDidChangeRefreshStatus = ( 64 status: RefreshStatus, 65): [RefreshCallback, RefreshStatus] => { 66 const cb: RefreshCallback = () => { 67 didChangeRefreshStatus.fire(status); 68 return OK; 69 }; 70 71 return [cb, status]; 72}; 73 74/** 75 * Link the refresh manager state machine to the VSC event system. 76 * 77 * The refresh manager needs to remain editor-agnostic so it can be used outside 78 * of VSC. It also has a more constrained event system that isn't completely 79 * represented by the VSC event system. This function links the two, such that 80 * any refresh manager state changes also trigger a VSC event that can be 81 * subscribed to by things that need to be notified or updated when the refresh 82 * manager runs, but don't need to be integrated into the refresh manager 83 * itself. 84 */ 85export function linkRefreshManagerToEvents( 86 refreshManager: RefreshManager<any>, 87) { 88 refreshManager.on(...fireDidChangeRefreshStatus('idle')); 89 refreshManager.on(...fireDidChangeRefreshStatus('willRefresh')); 90 refreshManager.on(...fireDidChangeRefreshStatus('refreshing')); 91 refreshManager.on(...fireDidChangeRefreshStatus('didRefresh')); 92 refreshManager.on(...fireDidChangeRefreshStatus('abort')); 93 refreshManager.on(...fireDidChangeRefreshStatus('fault')); 94} 95