Skip to content

Commit

Permalink
feature: add configuration options to the extension (#132)
Browse files Browse the repository at this point in the history
* fix: add missing configuration contribution

* refactor: add file reference config options

* chore: add settings tests

* Revert "chore: add settings tests"

This reverts commit 050bce9.
  • Loading branch information
byCedric authored Sep 3, 2022
1 parent 3dcd3b3 commit 3b2d38b
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 41 deletions.
40 changes: 39 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,45 @@
"command": "expo.config.prebuild.preview.json",
"title": "Preview modifier as JSON"
}
]
],
"configuration": {
"title": "Expo Tools",
"properties": {
"expo.appManifest.pluginValidation": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "Validate the config plugins in app manifests, listed under \"expo.plugins\". This only applies to \"app.json\" and \"app.config.json\" files.",
"markdownDescription": "Validate the config plugins in app manifests, listed under `expo.plugins`. This only applies to `app.json` and `app.config.json` files."
},
"expo.appManifest.fileReferences": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "Enable suggestions for file references in app manifests, like the splash screen. This only applies to \"app.json\" and \"app.config.json\" files.",
"markdownDescription": "Enable suggestions for file references in app manifests, like the splash screen This only applies to `app.json` and `app.config.json` files."
},
"expo.appManifest.fileReferences.showHiddenFiles": {
"type": "boolean",
"default": false,
"scope": "resource",
"description": "Show hidden file suggestions for file references in app manifests, like the icon image.",
"markdownDescription": "Show hidden file suggestions for file references in app manifests, like the icon image."
},
"expo.appManifest.fileReferences.excludeGlobPatterns": {
"type": "object",
"patternProperties": {
".*": {
"type": "boolean",
"default": true,
"description": "Enable or disable file references matching the glob pattern."
}
},
"scope": "resource",
"description": "Exclude file suggestions for file references in app manifest, using glob patterns."
}
}
}
},
"scripts": {
"postinstall": "patch-package",
Expand Down
29 changes: 8 additions & 21 deletions src/completion/provider/configuration/getConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,27 @@
import * as vscode from 'vscode';

import { getManifestFileReferencesConfig } from '../../../settings';
import { parseMappings, replaceWorkspaceFolder, Mapping } from './getMapping';
import { getWorkfolderTsConfigConfiguration } from './getTsconfig';

export interface Config {
export interface Config
extends Omit<ReturnType<typeof getManifestFileReferencesConfig>, 'mappings'> {
mappings: Mapping[];
showHiddenFiles: boolean;
withExtension: boolean;
absolutePathToWorkspace: boolean;
filesExclude: Record<string, string>;
}

export async function getConfiguration(resource: vscode.Uri): Promise<Readonly<Config>> {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(resource);
const config = getManifestFileReferencesConfig(resource);
const mappings = await getMappings(config.mappings, workspaceFolder);

const getConfig = (key: string) => vscode.workspace.getConfiguration(key, resource);

const cfgExtension = getConfig('expo-config-intellisense');
const cfgGeneral = getConfig('files');

const mappings = await getMappings(cfgExtension, workspaceFolder);

return {
showHiddenFiles: cfgExtension['showHiddenFiles'],
withExtension: cfgExtension['extensionOnImport'],
absolutePathToWorkspace: cfgExtension['absolutePathToWorkspace'],
filesExclude: cfgGeneral['exclude'],
mappings,
};
return { ...config, mappings };
}

async function getMappings(
configuration: vscode.WorkspaceConfiguration,
configuredMappings?: Record<string, string> | null,
workfolder?: vscode.WorkspaceFolder
): Promise<Mapping[]> {
const mappings = parseMappings(configuration.mappings || {});
const mappings = parseMappings(configuredMappings || {});
const tsConfigMappings = await getWorkfolderTsConfigConfiguration(workfolder);
const allMappings = [...mappings, ...tsConfigMappings];
return replaceWorkspaceFolder(allMappings, workfolder);
Expand Down
5 changes: 5 additions & 0 deletions src/completion/provider/provideCompletionItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import JsonFile from '@expo/json-file';
import * as path from 'path';
import * as vscode from 'vscode';

import { isManifestFileReferencesEnabled } from '../../settings';
import { Config, getConfiguration } from './configuration/getConfiguration';
import { createNodeModuleItem, createPathCompletionItem } from './createCompletionItem';
import { Context, createContext, ResolveType } from './createContext';
Expand All @@ -12,6 +13,10 @@ export async function provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position
): Promise<vscode.CompletionItem[]> {
if (!isManifestFileReferencesEnabled(document)) {
return [];
}

const context = createContext(document, position);

if (!context) {
Expand Down
20 changes: 11 additions & 9 deletions src/manifest/configPlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import {
workspace,
} from 'vscode';

import { isManifestFileReferencesEnabled, isManifestPluginValidationEnabled } from '../settings';
import { getProjectRoot } from '../utils/getProjectRoot';
import { iterateFileReferences } from './fileReferences';
import { isConfigPluginValidationEnabled } from './settings';
import { ThrottledDelayer } from './utils/async';
import {
iteratePluginNames,
Expand Down Expand Up @@ -66,13 +66,15 @@ export function setupDefinition() {
});

// Add links for any random file references starting with `"./` that aren't inside of the `plugins` array.
iterateFileReferences(document, node, ({ range, fileReference }) => {
const filePath = path.join(projectRoot, fileReference);
const linkUri = Uri.file(filePath);
const link = new DocumentLink(range, linkUri);
link.tooltip = 'Go to asset';
links.push(link);
});
if (isManifestFileReferencesEnabled(document)) {
iterateFileReferences(document, node, ({ range, fileReference }) => {
const filePath = path.join(projectRoot, fileReference);
const linkUri = Uri.file(filePath);
const link = new DocumentLink(range, linkUri);
link.tooltip = 'Go to asset';
links.push(link);
});
}

return links;
},
Expand Down Expand Up @@ -120,7 +122,7 @@ function clearDiagnosticCollection() {
}

async function validateDocument(document: TextDocument) {
if (!isConfigPluginValidationEnabled(document)) {
if (!isManifestPluginValidationEnabled(document)) {
clearDiagnosticCollection();
return;
}
Expand Down
10 changes: 0 additions & 10 deletions src/manifest/settings.ts

This file was deleted.

39 changes: 39 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ConfigurationScope, workspace } from 'vscode';

/**
* Determine if we should validate the config plugins within app manifests.
* This uses the `expo.appManifest.pluginValidation` setting from the configuration scope.
*/
export function isManifestPluginValidationEnabled(scope?: ConfigurationScope) {
return workspace
.getConfiguration('expo.appManifest', scope)
.get<boolean>('pluginValidation', true);
}

/**
* Determine if we should show file references auto-complete in app manifests.
* This uses the `expo.appManifest.fileReferences` setting from the configuration scope.
*/
export function isManifestFileReferencesEnabled(scope?: ConfigurationScope) {
return workspace.getConfiguration('expo.appManifest', scope).get<boolean>('fileReferences', true);
}

/**
* Get the manifest file references configuration set.
* This uses multiple settings from the configuration scope.
* - `expo.appManifest.fileReferences.showHiddenFiles`
* - `expo.appManifest.fileReferences.excludeGlobPatterns`
* - `expo.appManifest.fileReferences.useAbsolutePathsForFileReferences` (hidden)
* - `expo.appManifest.fileReferences.mappings` (hidden)
*/
export function getManifestFileReferencesConfig(scope?: ConfigurationScope) {
const config = workspace.getConfiguration('expo.appManifest.fileReferences', scope);

return {
showHiddenFiles: config.get<boolean>('showHiddenFiles', false),
filesExclude: config.get<Record<string, string> | null>('excludeGlobPatterns', null),
// TODO(cedric): Check if the settings blow this comment are still required
absolutePathToWorkspace: config.get<boolean>('useAbsolutePathsForFileReferences', false),
mappings: config.get<Record<string, string> | null>('mappings', null),
};
}

0 comments on commit 3b2d38b

Please sign in to comment.