vscode#ProgressLocation TypeScript Examples

The following examples show how to use vscode#ProgressLocation. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: vscodeNotificator.ts    From google-drive-vscode with MIT License 6 votes vote down vote up
showProgressMessage(message: string, task: Promise<any>): void {
        window.withProgress({
            location: ProgressLocation.Notification,
            title: message,
        }, () => {
            const p = new Promise((resolve, reject) => {
                task.then(() => resolve())
                    .catch(err => reject(err));
            });
            return p;
        });
    }
Example #2
Source File: extension.ts    From language-tools with MIT License 6 votes vote down vote up
function addCompilePreviewCommand(getLS: () => LanguageClient, context: ExtensionContext) {
    const compiledCodeContentProvider = new CompiledCodeContentProvider(getLS);

    context.subscriptions.push(
        workspace.registerTextDocumentContentProvider(
            CompiledCodeContentProvider.scheme,
            compiledCodeContentProvider
        ),
        compiledCodeContentProvider
    );

    context.subscriptions.push(
        commands.registerTextEditorCommand('svelte.showCompiledCodeToSide', async (editor) => {
            if (editor?.document?.languageId !== 'svelte') {
                return;
            }

            const uri = editor.document.uri;
            const svelteUri = CompiledCodeContentProvider.toSvelteSchemeUri(uri);
            window.withProgress(
                { location: ProgressLocation.Window, title: 'Compiling..' },
                async () => {
                    return await window.showTextDocument(svelteUri, {
                        preview: true,
                        viewColumn: ViewColumn.Beside
                    });
                }
            );
        })
    );
}
Example #3
Source File: leanInstaller.ts    From vscode-lean4 with Apache License 2.0 6 votes vote down vote up
private async executeWithProgress(prompt: string, cmd: string, options: string[], workingDirectory: string | null): Promise<string>{
        let inc = 0;
        let stdout = ''
        /* eslint-disable  @typescript-eslint/no-this-alias */
        const realThis = this;
        await window.withProgress({
            location: ProgressLocation.Notification,
            title: '',
            cancellable: false
        }, (progress) => {
            const progressChannel : OutputChannel = {
                name : 'ProgressChannel',
                append(value: string)
                {
                    stdout += value;
                    if (realThis.outputChannel){
                        // add the output here in case user wants to go look for it.
                        realThis.outputChannel.appendLine(value.trim());
                    }
                    if (inc < 100) {
                        inc += 10;
                    }
                    progress.report({ increment: inc, message: value });
                },
                appendLine(value: string) {
                    this.append(value + '\n');
                },
                replace(value: string) { /* empty */ },
                clear() { /* empty */ },
                show() { /* empty */ },
                hide() { /* empty */ },
                dispose() { /* empty */ }
            }
            progress.report({increment:0, message: prompt});
            return batchExecute(cmd, options, workingDirectory, progressChannel);
        });
        return stdout;
    }
Example #4
Source File: dbtCommandQueue.ts    From vscode-dbt-power-user with MIT License 6 votes vote down vote up
private async pickCommandToRun(): Promise<void> {
    if (!this.running && this.queue.length > 0) {
      this.running = true;
      const { command, statusMessage, focus } = this.queue.shift()!;

      await window.withProgress(
        {
          location: focus
            ? ProgressLocation.Notification
            : ProgressLocation.Window,
          cancellable: true,
          title: statusMessage,
        },
        async (_, token) => {
          await command(token);
        }
      );

      this.running = false;
      this.pickCommandToRun();
    }
  }
Example #5
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async dev(nextPath: string) {
    const out = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "starting server.",
        cancellable: true,
      },
      async () => {
        const out = await NextjsExportPodUtils.startNextDev({
          nextPath,
          quiet: true,
        });
        return out;
      }
    );
    return out;
  }
Example #6
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async export(nextPath: string) {
    await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Exporting... this may take a while.",
        cancellable: false,
      },
      async () => {
        const out = await NextjsExportPodUtils.startNextExport({
          nextPath,
          quiet: true,
        });
        return out;
      }
    );
  }
Example #7
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async build(
    cmd: ExportPodCommand,
    podChoice: PodItemV4,
    podConfig: NextjsExportConfig
  ) {
    // todo: handle override.
    await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Building...",
        cancellable: false,
      },
      async () => {
        const out = cmd.execute({ podChoice, config: podConfig, quiet: true });
        return out;
      }
    );
  }
Example #8
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async clone(nextPath: string) {
    await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Cloning NextJS template...",
        cancellable: false,
      },
      async () => {
        const out = await NextjsExportPodUtils.cloneTemplate({
          nextPath,
        });
        return out;
      }
    );
  }
Example #9
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async install(nextPath: string) {
    await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Installing dependencies... This may take a while.",
        cancellable: false,
      },
      async () => {
        const out = await NextjsExportPodUtils.installDependencies({
          nextPath,
        });
        return out;
      }
    );
  }
Example #10
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async removeNextPath(nextPath: string) {
    await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "removing NextJS template directory...",
        cancellable: false,
      },
      async () => {
        const out = await NextjsExportPodUtils.removeNextPath({
          nextPath,
        });
        return out;
      }
    );
  }
Example #11
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
static async isInitialized(wsRoot: string) {
    const out = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Checking if NextJS template is initialized",
        cancellable: false,
      },
      async () => {
        const out = await NextjsExportPodUtils.isInitialized({
          wsRoot,
        });
        return out;
      }
    );
    return out;
  }
Example #12
Source File: NotionExportPodCommand.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
getAllNotionPages = async (apiKey: string) => {
    const pagesMap = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Fetching Parent Pages...",
        cancellable: false,
      },
      async () => {
        const notion = new Client({
          auth: apiKey,
        });
        const allDocs = await notion.search({
          sort: { direction: "descending", timestamp: "last_edited_time" },
          filter: { value: "page", property: "object" },
        });
        const pagesMap: { [key: string]: string } = {};
        const pages = allDocs.results as Page[];
        pages.map((page: Page) => {
          const key = this.getPageName(page);
          const value = page.id;
          pagesMap[key] = value;
        });
        return pagesMap;
      }
    );
    return pagesMap;
  };
Example #13
Source File: AddAndCommit.ts    From dendron with GNU Affero General Public License v3.0 6 votes vote down vote up
async execute(opts?: CommandOpts) {
    const ctx = "execute";
    L.info({ ctx, opts });
    const engine = ExtensionProvider.getEngine();
    const workspaceService = ExtensionProvider.getExtension().workspaceService;
    if (_.isUndefined(workspaceService))
      throw new DendronError({
        message: "Workspace is not initialized",
        severity: ERROR_SEVERITY.FATAL,
      });
    const committed = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Workspace Add and Commit",
        cancellable: false,
      },
      async (progress) => {
        progress.report({ message: "staging changes" });
        const committed = await workspaceService.commitAndAddAll({
          engine,
        });
        L.info(committed);
        return committed;
      }
    );
    const { message, maxMessageSeverity } = AddAndCommit.generateReportMessage({
      committed,
    });
    const committedDone = WorkspaceUtils.getCountForStatusDone(committed);
    const repos = (count: number) => (count <= 1 ? "repo" : "repos");
    message.push(`Committed ${committedDone} ${repos(committedDone)}`);
    const finalMessage = message.join(" ");
    VSCodeUtils.showMessage(maxMessageSeverity, finalMessage, {});
    return { committed, finalMessage };
  }
Example #14
Source File: pods.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
withProgressOpts = {
  withProgress: window.withProgress,
  location: ProgressLocation.Notification,
  showMessage: window.showInformationMessage,
}
Example #15
Source File: VaultAddCommand.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
async handleRemoteRepo(
    opts: CommandOpts
  ): Promise<{ vaults: DVault[]; workspace?: DWorkspace }> {
    const { vaults, workspace } = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Adding remote vault",
        cancellable: false,
      },
      async (progress) => {
        progress.report({
          message: "cloning repo",
        });
        const baseDir = ExtensionProvider.getDWorkspace().wsRoot;
        const git = simpleGit({ baseDir });
        await git.clone(opts.pathRemote!, opts.path);
        const { vaults, workspace } = await GitUtils.getVaultsFromRepo({
          repoPath: path.join(baseDir, opts.path),
          wsRoot: ExtensionProvider.getDWorkspace().wsRoot,
          repoUrl: opts.pathRemote!,
        });
        if (_.size(vaults) === 1 && opts.name) {
          vaults[0].name = opts.name;
        }
        // add all vaults
        progress.report({
          message: "adding vault",
        });
        const wsRoot = ExtensionProvider.getDWorkspace().wsRoot;
        const wsService = new WorkspaceService({ wsRoot });

        if (workspace) {
          await wsService.addWorkspace({ workspace });
          await this.addWorkspaceToWorkspace(workspace);
        } else {
          // Some things, like updating config, can't be parallelized so needs to be done one at a time
          for (const vault of vaults) {
            // eslint-disable-next-line no-await-in-loop
            await wsService.createVault({ vault });
            // eslint-disable-next-line no-await-in-loop
            await this.addVaultToWorkspace(vault);
          }
        }
        return { vaults, workspace };
      }
    );
    return { vaults, workspace };
  }
Example #16
Source File: Sync.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
async execute(opts?: CommandOpts) {
    const ctx = "execute";
    L.info({ ctx, opts });
    const workspaceService = ExtensionProvider.getExtension().workspaceService;
    if (_.isUndefined(workspaceService))
      throw new DendronError({
        message: "Workspace is not initialized",
        severity: ERROR_SEVERITY.FATAL,
      });
    const engine = ExtensionProvider.getEngine();

    const { committed, pulled, pushed } = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Syncing Workspace",
        cancellable: false,
      },
      async (progress) => {
        progress.report({ increment: 0, message: "committing repos" });
        const committed = await workspaceService.commitAndAddAll({ engine });
        L.info(committed);
        progress.report({ increment: 25, message: "pulling repos" });
        const pulled = await workspaceService.pullVaults();
        L.info(pulled);
        progress.report({ increment: 50, message: "pushing repos" });

        const pushed = await workspaceService.pushVaults();
        progress.report({ increment: 100 });
        L.info(pushed);

        return { committed, pulled, pushed };
      }
    );

    const { message, maxMessageSeverity } = SyncCommand.generateReportMessage({
      committed,
      pulled,
      pushed,
    });

    // Successful operations
    const committedDone = WorkspaceUtils.getCountForStatusDone(committed);
    const pulledDone = WorkspaceUtils.getCountForStatusDone(pulled);
    const pushedDone = WorkspaceUtils.getCountForStatusDone(pushed);
    const repos = (count: number) => (count === 1 ? "repo" : "repos");
    message.push(`Committed ${committedDone} ${repos(committedDone)},`);
    message.push(`tried pulling ${pulledDone}`);
    message.push(`and pushing ${pushedDone} ${repos(pushedDone)}.`);
    const finalMessage = message.join(" ");

    VSCodeUtils.showMessage(maxMessageSeverity, finalMessage, {});

    return {
      committed,
      pulled,
      pushed,
      finalMessage,
    };
  }
Example #17
Source File: RefactorHierarchyV2.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
async execute(opts: CommandOpts): Promise<any> {
    const ctx = "RefactorHierarchy:execute";
    const { scope, match, replace, noConfirm } = opts;
    this.L.info({ ctx, opts, msg: "enter" });
    const ext = getExtension();
    const { engine } = getDWorkspace();
    const matchRE = new RegExp(match);
    const capturedNotes = this.getCapturedNotes({
      scope,
      matchRE,
      engine,
    });

    const operations = this.getRenameOperations({
      capturedNotes,
      matchRE,
      replace,
      wsRoot: engine.wsRoot,
    });

    if (await this.hasExistingFiles({ operations })) {
      return;
    }

    await this.showPreview(operations);

    const shouldProceed = await this.promptConfirmation(noConfirm);
    if (!shouldProceed) {
      window.showInformationMessage("Cancelled");
      return;
    }

    if (ext.fileWatcher) {
      ext.fileWatcher.pause = true;
    }
    const renameCmd = new RenameNoteV2aCommand();
    const out = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Refactoring...",
        cancellable: false,
      },
      async () => {
        const out = await this.runOperations({ operations, renameCmd });
        return out;
      }
    );
    return out;
  }
Example #18
Source File: MoveNoteCommand.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
async execute(opts: CommandOpts): Promise<{ changed: NoteChangeEntry[] }> {
    const ctx = "MoveNoteCommand:execute";

    opts = _.defaults(opts, {
      closeAndOpenFile: true,
      allowMultiselect: true,
    });

    const { engine } = getDWorkspace();
    const ext = getExtension();

    if (ext.fileWatcher && !opts.noPauseWatcher) {
      ext.fileWatcher.pause = true;
    }
    try {
      this.L.info({ ctx, opts });

      if (isMultiMove(opts.moves)) {
        await this.showMultiMovePreview(opts.moves);
        const result = await QuickPickUtil.showProceedCancel();

        if (result !== ProceedCancel.PROCEED) {
          window.showInformationMessage("cancelled");
          return { changed: [] };
        }
      }

      const changed = await window.withProgress(
        {
          location: ProgressLocation.Notification,
          title: "Refactoring...",
          cancellable: false,
        },
        async () => {
          const allChanges = await this.moveNotes(engine, opts.moves);
          return allChanges;
        }
      );

      if (opts.closeAndOpenFile) {
        // During bulk move we will only open a single file that was moved to avoid
        // cluttering user tabs with all moved files.
        await closeCurrentFileOpenMovedFile(engine, opts.moves[0]);
      }
      return { changed };
    } finally {
      if (ext.fileWatcher && !opts.noPauseWatcher) {
        setTimeout(() => {
          if (ext.fileWatcher) {
            ext.fileWatcher.pause = false;
          }
          this.L.info({ ctx, msg: "exit" });
        }, 3000);
      }
    }
  }
Example #19
Source File: ImportPod.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
async execute(opts: CommandOpts) {
    const ctx = { ctx: "ImportPod" };
    this.L.info({ ctx, msg: "enter", podChoice: opts.podChoice.id });
    const wsRoot = getDWorkspace().wsRoot;
    const utilityMethods = {
      getGlobalState,
      updateGlobalState,
      showDocumentQuickPick,
      showInputBox,
      openFileInEditor,
      handleConflict,
    };
    if (!wsRoot) {
      throw Error("ws root not defined");
    }
    const { engine, vaults } = getDWorkspace();
    const pod = new opts.podChoice.podClass() as ImportPod; // eslint-disable-line new-cap
    const fileWatcher = getExtension().fileWatcher;
    if (fileWatcher) {
      fileWatcher.pause = true;
    }
    const importedNotes = await window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Finding documents...",
        cancellable: false,
      },
      async () => {
        const { importedNotes, errors } = await pod.execute({
          config: opts.config,
          engine,
          wsRoot,
          vaults,
          utilityMethods,
          onPrompt: async (type?: PROMPT) => {
            const resp =
              type === PROMPT.USERPROMPT
                ? await window.showInformationMessage(
                    "Do you want to overwrite",
                    { modal: true },
                    { title: "Yes" }
                  )
                : window.showInformationMessage(
                    "Note is already in sync with the google doc"
                  );
            return resp;
          },
        });

        if (errors && errors.length > 0) {
          let errorMsg = `Error while importing ${errors.length} notes:\n`;
          errors.forEach((e) => {
            errorMsg += e.path + "\n";
          });
          window.showErrorMessage(errorMsg);
        }

        return importedNotes;
      }
    );
    await new ReloadIndexCommand().execute();
    if (fileWatcher) {
      fileWatcher.pause = false;
    }
    window.showInformationMessage(
      `${importedNotes.length} notes imported successfully.`
    );
  }
Example #20
Source File: site.ts    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
static async handlePublishTarget(
    target: PublishTarget,
    nextPath: string,
    wsRoot: string
  ) {
    switch (target) {
      case PublishTarget.GITHUB: {
        const docsPath = path.join(wsRoot, "docs");
        const outPath = path.join(nextPath, "out");
        await window.withProgress(
          {
            location: ProgressLocation.Notification,
            title: "Building Github target...",
            cancellable: false,
          },
          async () => {
            const docsExist = fs.pathExistsSync(docsPath);
            if (docsExist) {
              const docsRemovePromptOut = await VSCodeUtils.showQuickPick(
                ["Don't remove.", "Remove"],
                {
                  title: "Docs folder already exists. Remove and continue??",
                  ignoreFocusOut: true,
                }
              );
              if (docsRemovePromptOut === "Don't remove") {
                window.showInformationMessage("Exiting.");
                return;
              }
              window.showInformationMessage("Removing /docs");
              fs.removeSync(docsPath);
            }
            fs.moveSync(outPath, docsPath);
            fs.ensureFileSync(path.join(docsPath, ".nojekyll"));
          }
        );
        window.showInformationMessage(
          `Done exporting. files available at ${docsPath}`
        );
        return;
      }
      default:
        assertUnreachable(target);
    }
  }
Example #21
Source File: installSM.ts    From sourcepawn-vscode with MIT License 5 votes vote down vote up
export async function run(args: any) {
  if (!existsSync(outputDir)) {
    mkdirSync(outputDir);
  }
  await window.withProgress(
    {
      location: ProgressLocation.Notification,
      title: "Sourcemod Download",
      cancellable: true,
    },
    async (progress, token) => {
      return downloadSM(progress, token);
    }
  );
  let spCompPath =
    Workspace.getConfiguration("sourcepawn").get<string>("SpcompPath") || "";
  let smHome =
    Workspace.getConfiguration("sourcepawn").get<string>("SourcemodHome") || "";
  let smDir = join(outputDir, "addons/sourcemod/scripting/include");
  let spComp: string;
  if (Platform === "win32") {
    spComp = join(outputDir, "addons/sourcemod/scripting/spcomp.exe");
  } else {
    spComp = join(outputDir, "addons/sourcemod/scripting/spcomp");
  }
  if (spCompPath != "" || smHome != "") {
    window
      .showInformationMessage(
        "The setting for SpcompPath or SourcemodHome is not empty, do you want to override them ?",
        "Yes",
        "No"
      )
      .then((choice) => {
        if (choice === "Yes") {
          updatePath(smDir, spComp);
        }
      });
    return 0;
  }
  updatePath(smDir, spComp);
  return 0;
}
Example #22
Source File: Controller.ts    From vscode-alxmldocumentation with MIT License 5 votes vote down vote up
/**
     * Initialize AL XML Documentation.
     */
    public async Initialize() {
        try 
        {
            await window.withProgress({
                location: ProgressLocation.Window,
                title: 'AL XML Documentation initialization in progress...',
            }, async (progress, token) => {
                let workspacePaths = workspace.workspaceFolders;
                if ((!workspacePaths) || (workspacePaths === undefined)) {
                    throw new Error('Workspace folders could not be retrieved.');
                }
    
                for (let validPath of workspacePaths) {
                    let allFiles = await workspace.findFiles(new RelativePattern(validPath, '**/*.al'), undefined, undefined, token);
                    let relevantFileTasks = allFiles.map(async (file: Uri) => {
                        let content = await readFile(file.fsPath, 'utf-8');
                        if (content.match(/(procedure|trigger|event)\s+(.*?)\(/gm)) {
                            return { uri: file, content: content };
                        }
    
                        return undefined;
                    });
                    let relevantFiles = await Promise.all(relevantFileTasks);
                    relevantFiles = relevantFiles.filter(f => f);
    
                    let tasks: Array<Promise<void>> = [];
                    let task = async (file: { uri: Uri, content: string }) => {
                        let document = Object.assign({});
                        document.getText = () => file.content;
                        document.fileName = file.uri.fsPath;
                        document.uri = file.uri;
                        
                        ALSyntaxUtil.GetALObject(document as any);
                    };
                    let max = relevantFiles.length;
                    for (let i = 0; i < max; i++) {
                        let file = relevantFiles[i];
                        tasks.push(task(file!));
    
                        if (i % 500 === 0) {
                            await Promise.all(tasks);
                            tasks = [];
                        }
                    }
    
                    if (tasks.length > 0) {
                        await Promise.all(tasks);
                    }
                }
    
                return true;
            });
        }
        catch (ex)
        {
            console.debug(ex);
        }
    }
Example #23
Source File: findFileReferences.ts    From language-tools with MIT License 5 votes vote down vote up
/**
 * adopted from https://github.com/microsoft/vscode/blob/5f3e9c120a4407de3e55465588ce788618526eb0/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts
 */
export async function addFindFileReferencesListener(
    getLS: () => LanguageClient,
    context: ExtensionContext
) {
    const disposable = commands.registerCommand('svelte.typescript.findAllFileReferences', handler);

    context.subscriptions.push(disposable);

    async function handler(resource?: Uri) {
        if (!resource) {
            resource = window.activeTextEditor?.document.uri;
        }

        if (!resource || resource.scheme !== 'file') {
            return;
        }

        const document = await workspace.openTextDocument(resource);

        await window.withProgress(
            {
                location: ProgressLocation.Window,
                title: 'Finding file references'
            },
            async (_, token) => {
                const lsLocations = await getLS().sendRequest<LSLocation[] | null>(
                    '$/getFileReferences',
                    document.uri.toString(),
                    token
                );

                if (!lsLocations) {
                    return;
                }

                const config = workspace.getConfiguration('references');
                const existingSetting = config.inspect<string>('preferredLocation');

                await config.update('preferredLocation', 'view');
                try {
                    await commands.executeCommand(
                        'editor.action.showReferences',
                        resource,
                        new Position(0, 0),
                        lsLocations.map(
                            (ref) =>
                                new Location(
                                    Uri.parse(ref.uri),
                                    new Range(
                                        ref.range.start.line,
                                        ref.range.start.character,
                                        ref.range.end.line,
                                        ref.range.end.character
                                    )
                                )
                        )
                    );
                } finally {
                    await config.update(
                        'preferredLocation',
                        existingSetting?.workspaceFolderValue ?? existingSetting?.workspaceValue
                    );
                }
            }
        );
    }
}
Example #24
Source File: VaultConvert.ts    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * Returns all vaults added
   * @param opts
   * @returns
   */
  async execute(opts: CommandOpts) {
    const ctx = "VaultConvertCommand";
    const { vault, type, remoteUrl } = opts;
    const { wsRoot } = getDWorkspace();
    if (!vault || !type)
      throw new DendronError({
        message:
          "Vault or type has not been specified when converting a vault.",
        payload: { vault, type, remoteUrl },
      });
    const workspaceService = getExtension().workspaceService;
    if (!workspaceService)
      throw new DendronError({
        message: "Workspace service is not available when converting a vault.",
        payload: { vault, type, remoteUrl },
      });

    if (type === "local") {
      await window.withProgress(
        {
          location: ProgressLocation.Notification,
          cancellable: false,
          title: "Converting vault to local",
        },
        async (progress) => {
          Logger.info({ ctx, msg: "Converting vault to local", vault, wsRoot });
          await workspaceService.convertVaultLocal({ wsRoot, vault });
          progress.report({ increment: 50 });
          // Reload the index to use the updated config
          await new ReloadIndexCommand().run({ silent: true });
          progress.report({ increment: 50 });
          window.showInformationMessage(
            `Converted vault '${VaultUtils.getName(vault)}' to a ${type} vault.`
          );
          Logger.info({
            ctx,
            msg: "Done converting vault to local",
            vault,
            wsRoot,
          });
        }
      );
      return { updatedVault: vault };
    } else if (type === "remote") {
      if (!remoteUrl)
        throw new DendronError({
          message: "Remote URL for remote vault has not been specified.",
          payload: { vault, type, remoteUrl },
        });
      await window.withProgress(
        {
          location: ProgressLocation.Notification,
          cancellable: false,
          title: "Converting vault to remote",
        },
        async (progress) => {
          Logger.info({
            ctx,
            msg: "Converting vault to remote",
            vault,
            wsRoot,
            remoteUrl,
          });
          const results = await workspaceService.convertVaultRemote({
            wsRoot,
            vault,
            remoteUrl,
          });
          progress.report({ increment: 50 });

          // Reload the index to use the updated config
          await new ReloadIndexCommand().run({ silent: true });
          progress.report({ increment: 50 });
          window.showInformationMessage(
            `Converted vault '${VaultUtils.getName(
              vault
            )}' to a ${type} vault. Remote set to ${results.remote} on branch ${
              results.branch
            }`
          );
          Logger.info({
            ctx,
            msg: "Done converting vault to remote",
            vault,
            wsRoot,
            remoteUrl,
          });
        }
      );

      return { updatedVault: vault };
    } else {
      assertUnreachable(type);
    }
  }
Example #25
Source File: VaultAddCommand.ts    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
async handleRemoteRepoSelfContained(
    opts: CommandOpts
  ): Promise<{ vaults: DVault[] }> {
    return window.withProgress(
      {
        location: ProgressLocation.Notification,
        title: "Adding remote vault",
        cancellable: false,
      },
      async (progress) => {
        const { wsRoot } = ExtensionProvider.getDWorkspace();
        progress.report({
          message: "cloning repo",
          increment: 0,
        });
        const { name, pathRemote: remoteUrl } = opts;
        const localUrl = path.join(wsRoot, opts.path);
        if (!remoteUrl) {
          throw new DendronError({
            message:
              "Remote vault has no remote set. This should never happen, please send a bug report if you encounter this.",
          });
        }

        await fs.ensureDir(localUrl);
        const git = new Git({ localUrl, remoteUrl });
        // `.` so it clones into the `localUrl` directory, not into a subdirectory of that
        await git.clone(".");
        const { vaults, workspace } = await GitUtils.getVaultsFromRepo({
          repoPath: localUrl,
          wsRoot,
          repoUrl: remoteUrl,
        });
        if (_.size(vaults) === 1 && name) {
          vaults[0].name = name;
        }
        // add all vaults
        const increment = 100 / (vaults.length + 1);
        progress.report({
          message:
            vaults.length === 1
              ? "adding vault"
              : `adding ${vaults.length} vaults`,
          increment,
        });
        const wsService = new WorkspaceService({ wsRoot });

        if (workspace) {
          // This is a backwards-compatibility fix until workspace vaults are
          // deprecated. If what we cloned was a workspace, then move it where
          // Dendron expects it, because we can't override the path.
          const clonedWSPath = path.join(wsRoot, workspace.name);
          await fs.move(localUrl, clonedWSPath);
          // Because we moved the workspace, we also have to recompute the vaults config.
          workspace.vaults = (
            await GitUtils.getVaultsFromRepo({
              repoPath: clonedWSPath,
              repoUrl: remoteUrl,
              wsRoot,
            })
          ).vaults;
          // Then handle the workspace vault as usual, without self contained vault stuff
          await wsService.addWorkspace({ workspace });
          await this.addWorkspaceToWorkspace(workspace);
        } else {
          // Some things, like updating config, can't be parallelized so needs
          // to be done one at a time
          await asyncLoopOneAtATime(vaults, async (vault) => {
            if (VaultUtils.isSelfContained(vault)) {
              // eslint-disable-next-line no-await-in-loop
              await wsService.createSelfContainedVault({
                vault,
                addToConfig: true,
              });
            } else {
              // eslint-disable-next-line no-await-in-loop
              await wsService.createVault({ vault });
            }
            // eslint-disable-next-line no-await-in-loop
            await this.addVaultToWorkspace(vault);
            progress.report({ increment });
          });
        }
        wsService.dispose();
        return { vaults, workspace };
      }
    );
  }
Example #26
Source File: ReloadIndex.ts    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * Update index
   * @param opts
   */
  async execute(
    opts?: ReloadIndexCommandOpts
  ): Promise<DEngineClient | undefined> {
    const ctx = "ReloadIndex.execute";
    this.L.info({ ctx, msg: "enter" });
    const ws = ExtensionProvider.getDWorkspace();
    let initError: IDendronError | undefined;
    const { wsRoot, engine } = ws;

    // Check if there are any misconfigured self contained vaults.
    // Deliberately not awaiting this to avoid blocking the reload
    ReloadIndexCommand.checkAndPromptForMisconfiguredSelfContainedVaults({
      engine: ExtensionProvider.getEngine(),
    });

    // Fix up any broken vaults
    const reloadIndex = async () => {
      const autoFixActions = await Promise.all(
        engine.vaults.flatMap((vault) => {
          return [
            this.createRootSchemaIfMissing(wsRoot, vault),
            this.createRootNoteIfMissing(wsRoot, vault),
          ];
        })
      );
      if (autoFixActions.filter(isNotUndefined).length > 0) {
        AnalyticsUtils.track(WorkspaceEvents.AutoFix, {
          ...categorizeActions(autoFixActions),
          nonFatalInitError:
            initError && initError.severity === ERROR_SEVERITY.MINOR,
        });
      }

      const start = process.hrtime();
      const { error } = await engine.init();
      const durationEngineInit = getDurationMilliseconds(start);
      this.L.info({ ctx, durationEngineInit });

      // if fatal, stop initialization
      if (error && error.severity !== ERROR_SEVERITY.MINOR) {
        this.L.error({ ctx, error, msg: "unable to initialize engine" });
        return;
      }
      if (error) {
        // There may be one or more errors,
        const errors = errorsList(error);
        errors.forEach((error) => {
          if (DuplicateNoteError.isDuplicateNoteError(error) && error.code) {
            VSCodeUtils.showMessage(MessageSeverity.WARN, error.message, {});
            AnalyticsUtils.track(WorkspaceEvents.DuplicateNoteFound, {
              source: this.key,
            });
            this.L.info({ ctx, error, msg: "Duplicate note IDs found" });
          } else {
            // Warn about any errors not handled above
            this.L.error({
              ctx,
              error,
              msg: `Initialization error: ${error.message}`,
            });
          }
        });
        if (errors.length === 0) {
          // For backwards compatibility, warn if there are warnings that are
          // non-fatal errors not covered by the new error architecture
          this.L.error({ ctx, error, msg: "init error" });
        }
      }
      return autoFixActions;
    };

    if (!(opts && !opts.silent)) {
      await reloadIndex();
    } else {
      await window.withProgress(
        {
          location: ProgressLocation.Notification,
          title: "Reloading Index...",
          cancellable: false,
        },
        reloadIndex
      );
    }

    this.L.info({ ctx, msg: "exit", initError });
    return engine;
  }
Example #27
Source File: extension.ts    From language-tools with MIT License 4 votes vote down vote up
function addRenameFileListener(getLS: () => LanguageClient) {
    workspace.onDidRenameFiles(async (evt) => {
        const oldUri = evt.files[0].oldUri.toString(true);
        const parts = oldUri.split(/\/|\\/);
        const lastPart = parts[parts.length - 1];
        // If user moves/renames a folder, the URI only contains the parts up to that folder,
        // and not files. So in case the URI does not contain a '.', check for imports to update.
        if (
            lastPart.includes('.') &&
            !['.ts', '.js', '.json', '.svelte'].some((ending) => lastPart.endsWith(ending))
        ) {
            return;
        }

        window.withProgress(
            { location: ProgressLocation.Window, title: 'Updating Imports..' },
            async () => {
                const editsForFileRename = await getLS().sendRequest<LSWorkspaceEdit | null>(
                    '$/getEditsForFileRename',
                    // Right now files is always an array with a single entry.
                    // The signature was only designed that way to - maybe, in the future -
                    // have the possibility to change that. If that ever does, update this.
                    // In the meantime, just assume it's a single entry and simplify the
                    // rest of the logic that way.
                    {
                        oldUri,
                        newUri: evt.files[0].newUri.toString(true)
                    }
                );
                const edits = editsForFileRename?.documentChanges?.filter(TextDocumentEdit.is);
                if (!edits) {
                    return;
                }

                const workspaceEdit = new WorkspaceEdit();
                // We need to take into account multiple cases:
                // - A Svelte file is moved/renamed
                //      -> all updates will be related to that Svelte file, do that here. The TS LS won't even notice the update
                // - A TS/JS file is moved/renamed
                //      -> all updates will be related to that TS/JS file
                //      -> let the TS LS take care of these updates in TS/JS files, do Svelte file updates here
                // - A folder with TS/JS AND Svelte files is moved/renamed
                //      -> all Svelte file updates are handled here
                //      -> all TS/JS file updates that consist of only TS/JS import updates are handled by the TS LS
                //      -> all TS/JS file updates that consist of only Svelte import updates are handled here
                //      -> all TS/JS file updates that are mixed are handled here, but also possibly by the TS LS
                //         if the TS plugin doesn't prevent it. This trades risk of broken updates with certainty of missed updates
                edits.forEach((change) => {
                    const isTsOrJsFile =
                        change.textDocument.uri.endsWith('.ts') ||
                        change.textDocument.uri.endsWith('.js');
                    const containsSvelteImportUpdate = change.edits.some((edit) =>
                        edit.newText.endsWith('.svelte')
                    );
                    if (isTsOrJsFile && !containsSvelteImportUpdate) {
                        return;
                    }

                    change.edits.forEach((edit) => {
                        if (
                            isTsOrJsFile &&
                            !TsPlugin.isEnabled() &&
                            !edit.newText.endsWith('.svelte')
                        ) {
                            // TS plugin enabled -> all mixed imports are handled here
                            // TS plugin disabled -> let TS/JS path updates be handled by the TS LS, Svelte here
                            return;
                        }

                        // Renaming a file should only result in edits of existing files
                        workspaceEdit.replace(
                            Uri.parse(change.textDocument.uri),
                            new Range(
                                new Position(edit.range.start.line, edit.range.start.character),
                                new Position(edit.range.end.line, edit.range.end.character)
                            ),
                            edit.newText
                        );
                    });
                });
                workspace.applyEdit(workspaceEdit);
            }
        );
    });
}
Example #28
Source File: auto-sync-object-ids.ts    From al-objid with MIT License 4 votes vote down vote up
autoSyncObjectIds = async () => {
    let auto = false;
    switch (await UI.sync.showHowToAutoSync()) {
        case LABELS.AUTO_SYNC_PICK.FULL_AUTO:
            auto = true;
            break;
        case LABELS.AUTO_SYNC_PICK.LEARN_MORE:
            env.openExternal(Uri.parse(URLS.AUTO_SYNC));
            return;
        case LABELS.AUTO_SYNC_PICK.INTERACTIVE:
            break;
        default:
            return;
    }

    let result = await window.withProgress({ location: ProgressLocation.Notification }, async progress => {
        if (!workspace.workspaceFolders || !workspace.workspaceFolders.length)
            return autoSyncResult(AutoSyncResult.NoALFolders);

        // Pick folders
        let apps = auto ? WorkspaceManager.instance.alApps : await WorkspaceManager.instance.pickFolders();
        if (!apps || !apps.length) {
            return autoSyncResult(AutoSyncResult.SilentFailure);
        }

        // Find git repos that match picked folders
        progress.report({ message: "Connecting to Git..." });
        let repos: Uri[] = [];
        let repoFolders: PropertyBag<Uri[]> = {};
        let setup: AutoSyncConfiguration[] = [];
        let nonGit = createNewConfig();
        setup.push(nonGit);
        for (let app of apps) {
            let root = await Git.instance.getRepositoryRootUri(app.uri);
            if (!root) {
                nonGit.folders.push(app.uri);
                continue;
            }

            let repoPath = root.fsPath;
            if (!repoFolders[repoPath]) repoFolders[repoPath] = [];
            repoFolders[repoPath].push(app.uri);

            if (repos.find(repo => repo.fsPath === repoPath)) continue;

            if (!(await Git.instance.isClean(root))) return autoSyncResult(AutoSyncResult.GitDirty, root);
            repos.push(root);
        }

        // Iterate through all repos to obtain branch information
        let branches: PropertyBag<GitBranchInfo[] | null> = {};
        let i = 0;
        for (let repo of repos) {
            progress.report({
                message: `Fetching branch information for ${getRepoName(repo)} (${++i} of ${repos.length})...`,
            });

            // Fetch
            await Git.instance.fetch(repo);

            // Obtain branches
            branches[repo.fsPath] = await Git.instance.branches(repo);
            if (branches === null) {
                // For some reason, repository reports no branches
                continue;
            }
        }

        // Iterate through all repos and pick the branches
        for (let repo of repos) {
            let repoBranches = branches[repo.fsPath];
            if (repoBranches === null) continue;

            // Pick from list of branches
            if (repoBranches.length > 1 && !auto) {
                progress.report({
                    message: "Waiting for your branches selection...",
                });
                let quickPick = new QuickPickWrapper<GitBranchInfo>(
                    repoBranches.map(branch => ({
                        label: BranchInfo.getName(branch),
                        detail: BranchInfo.getDetail(branch),
                        description: "",
                        data: branch,
                    }))
                );
                quickPick.placeholder = `Which branches would you like to synchronize for ${getRepoName(repo)}?`;
                let picked = await quickPick.pickMany();
                if (!picked.length) continue;
                repoBranches = picked;
            }

            // For each branch, if local is ahead/behind, ask whether to use local, remote, or both (and also indicate how many commits is difference)
            let config: AutoSyncConfiguration = createNewConfig(repo);
            for (let branch of repoBranches) {
                progress.report({
                    message: `Progressing branch ${branch.name || branch.tracks} of ${getRepoName(repo)}`,
                });
                if (branch.ahead || branch.behind) {
                    if (auto) {
                        if (branch.ahead) config.branchesLocal.push(branch.name!);
                        if (branch.behind) config.branchesRemote.push(branch.name!);
                    } else {
                        let picks = [
                            `Local (${BranchInfo.getChooseLocalText(branch)})`,
                            `Remote (${BranchInfo.getChooseRemoteText(branch)})`,
                        ];
                        if (branch.ahead && branch.behind)
                            picks.push(`Both (includes all information from local and remote)`);
                        let choice = await window.showQuickPick(picks, {
                            placeHolder: `How do you want to synchronize branch ${branch.name} of ${getRepoName(
                                repo
                            )}?`,
                        });
                        if (!choice) continue;
                        switch (choice.split(" ")[0]) {
                            case "Local":
                                config.branchesLocal.push(branch.name!);
                                break;
                            case "Remote":
                                config.branchesRemote.push(branch.tracks!);
                                break;
                            case "Both":
                                config.branchesRemote.push(branch.tracks!);
                                config.branchesLocal.push(branch.name!);
                                break;
                        }
                    }
                } else {
                    if (branch.name) {
                        // If local branch exists, then it's used even if remote exists
                        config.branchesLocal.push(branch.name);
                    } else {
                        // If local branch does not exist, then it's a remote branch and must be used
                        config.branchesRemote.push(branch.tracks!);
                    }
                }
            }
            config.folders = repoFolders[repo.fsPath];
            setup.push(config);
        }

        let consumptions: PropertyBag<ConsumptionInfo> = {};
        for (let config of setup) {
            progress.report({
                message: `Finding object IDs in ${config.repo ? `repo ${getRepoName(config.repo)}` : "workspace"}...`,
            });
            await syncSingleConfiguration(config, consumptions);
        }
        compressConsumptions(consumptions, apps);
        let payload = authorizeConsumptions(consumptions, apps);

        Telemetry.instance.log("autoSyncIds");
        await Backend.autoSyncIds(payload, false);
        return autoSyncResult(AutoSyncResult.Success);
    });

    switch (result.status) {
        case AutoSyncResult.Success:
            output.log("[auto-sync-object-ids] Completed successfully.", LogLevel.Info);
            UI.sync.showSuccessInfo();
            break;
        case AutoSyncResult.NoALFolders:
            output.log("[auto-sync-object-ids] No AL folders found in the workspace.", LogLevel.Info);
            break;
        case AutoSyncResult.GitDirty:
            let repoName = getRepoName(result.context);
            output.log(`[auto-sync-object-ids] Git repository ${repoName} is dirty. Cannot auto sync.`, LogLevel.Info);
            if ((await UI.sync.showRepoNotClean(repoName)) === LABELS.BUTTON_LEARN_MORE) {
                env.openExternal(Uri.parse(URLS.AUTO_SYNC_DIRTY));
            }
            break;
    }
}