[FIXED] Load up workspace state on open vs code extension

Issue

I’ve been working on a vs code extension to make a button in the status bar that will run a script in the terminal. I have saved the state of the buttons and the custom user commands in context.workspaceState.

However, it only seems to load up when I trigger the command from the command palette and not from the initial load.

For example, I will open a new project that I had previously created a button on, and in the status bar it would not show. Then I will go to add button in the command palette, exit out of it, then the buttons in the status bar will show.

Do you know why this is happening?

extension.ts

import { commands, ExtensionContext } from 'vscode'
import {
  addButtonScript,
  deleteButtonScript,
  loadInitialState,
} from './buttonScripts'
import { resetStateScript, viewStateScript } from './debuggingHelpers'

export interface WorkspaceState {
  name: string
  command: string
}

export async function activate(context: ExtensionContext) {
  await loadInitialState(context)

  const deleteButton = commands.registerCommand('extension.deleteButton', () =>
    deleteButtonScript(context)
  )
  const addButton = commands.registerCommand('extension.addButton', () =>
    addButtonScript(context)
  )
  //debugging scripts
  const viewState = commands.registerCommand('extension.viewState', () =>
    viewStateScript(context)
  )
  const resetState = commands.registerCommand('extension.resetState', () =>
    resetStateScript(context)
  )

  context.subscriptions.push(addButton, deleteButton, viewState, resetState)
}

export function deactivate() {}

butonScripts.ts


import { window, ExtensionContext, commands } from 'vscode'
import { resetStateScript } from './debuggingHelpers'
import { WorkspaceState } from './extension'
import {
  createButton,
  addSingleObjectToState,
  getState,
  updateState,
} from './utilities'

export async function loadInitialState(context: ExtensionContext) {
  const initialState = await getState(context)
  // Load button state(s) is there is any
  if (!!initialState && initialState !== '') {
    const workspaceState: WorkspaceState[] = await JSON.parse(initialState!)
    workspaceState.forEach(({ name, command }) => createButton(name, command))
}

export async function addButtonScript(context: ExtensionContext) {
  const command = await window.showInputBox({
    prompt: 'Add in the script command you want to run in the terminal',
  })
  if (!command) return window.showErrorMessage('No command provided')

  const name = await nameInput()
  if (!name) return

  await createButton(name!, command!)
  await addSingleObjectToState({ context, name, command })
  return
}

export async function deleteButtonScript(context: ExtensionContext) {
  const currentState = await getState(context)

  if (!currentState || currentState === '[]') {
    window.showErrorMessage('No buttons to delete')
    return
  }
  const buttonNamesParsed: WorkspaceState[] = JSON.parse(currentState!)
  const buttonNames = buttonNamesParsed.map(({ name }) => name)

  const buttonSelection = await window.showQuickPick(
    [...buttonNames, `Delete all`],
    { title: 'Choose a button to delete. Warning: this will reload the window' }
  )
  if (!buttonSelection) return window.showErrorMessage('No button selected')
  if (buttonSelection === 'Delete all') resetStateScript(context)
  if (buttonSelection !== 'Delete all') {
    const newState = buttonNamesParsed.filter(
      ({ name }) => name !== buttonSelection
    )
    await updateState(context, newState)
  }
  commands.executeCommand('workbench.action.reloadWindow')
  return
}

async function nameInput() {
  const input = await window.showInputBox({
    prompt: 'Add the name of the button (max 5 characters)',
  })

  if (!input) {
    window.showErrorMessage('No name provided')
    return
  }
  if (input.length! > 5) {
    window.showErrorMessage('Name is too long')
    nameInput()
  }
  if (input.length < 6) return input
  return
}

Full repo is here if you need it – https://github.com/puyanwei/quick-scripts-v2

Solution

From your package.json:

  "activationEvents": [
    "onCommand:extension.addButton",
    "onCommand:extension.deleteButton"
  ],

So your extension only activates on triggering either of those commands.

Try this instead:

 "activationEvents": [
  "onStartupFinished"
 ],

so that your extension is activated once vscode startup is complete. You may find through intellisense other activationEvents that also work to activate your extension earlier.

Answered By – Mark

Answer Checked By – Cary Denson (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published