Skip to content

Instantly share code, notes, and snippets.

@SoMaCoSF
Created April 30, 2025 22:12
Show Gist options
  • Save SoMaCoSF/c4aacacfdf8fbfcb77ff83115f42709d to your computer and use it in GitHub Desktop.
Save SoMaCoSF/c4aacacfdf8fbfcb77ff83115f42709d to your computer and use it in GitHub Desktop.
Wanting Cursor to detect when a file referenced in an import statement doesn't exist and prompt "File X not found. Create it?"

Wanting Cursor to detect when a file referenced in an import statement doesn't exist and prompt "File X not found. Create it?"

I'll create a VS Code extension that detects missing imported files and offers to create them automatically.

Import Path File Creator Extension - Installation Instructions

This extension automatically detects when you're importing files that don't exist yet and offers to create them with appropriate templates - exactly what was requested in that Cursor forum thread about suggesting file creation from import paths.

Quick Installation Steps:

  1. Create a new VS Code extension project:

    npm init vscode-extension
    # Choose TypeScript when prompted
  2. Replace the files with those from the artifacts:

    • Replace src/extension.ts with the "Import Path File Creator Extension" artifact
    • Replace package.json with the "package.json for Import Path File Creator" artifact
  3. Install dependencies and build:

    npm install
    npm run compile
  4. Test the extension:

    • Press F5 in VS Code/Cursor to launch with the extension
    • Try writing an import statement for a non-existent file like:
      import styles from './About.module.scss'
    • Save the file
    • You'll get a notification offering to create the missing file
  5. Package for distribution (optional):

    npm install -g vsce
    vsce package
    code --install-extension import-file-creator-0.0.1.vsix

How It Works

The extension:

  1. Monitors your code files for import statements
  2. Detects when imported files don't exist
  3. Offers to create them with appropriate templates based on file type
  4. Automatically creates any necessary directories
  5. Opens the newly created file for editing

This should solve the exact problem mentioned in the forum thread where users want Cursor to detect missing imported files and offer to create them.

=======

README.md:

Import Path File Creator

A VS Code/Cursor extension that detects missing files in import statements and offers to create them with appropriate templates.

Overview

This extension solves a common pain point when coding: writing import statements for files that don't exist yet. Instead of having to manually create these files, this extension will:

  1. Automatically detect when you import a file that doesn't exist
  2. Offer to create the file for you with an appropriate template
  3. Open the newly created file so you can start editing it immediately

Features

  • Import Detection: Identifies missing files from ES6 imports, CommonJS requires, and CSS imports
  • Smart Path Resolution: Handles various import path formats and automatically adds extensions when needed
  • Contextual Templates: Creates files with appropriate starter code based on file type and context
  • Directory Creation: Automatically creates any missing directories in the import path
  • Multiple Language Support: Works with JavaScript, TypeScript, React, Vue, CSS, and more

Installation

  1. Clone this repository or create the files from scratch:

    git clone https://github.com/yourusername/import-file-creator.git
    cd import-file-creator
  2. Install dependencies:

    npm install
  3. Build the extension:

    npm run compile
  4. To test in development mode:

    • Press F5 in VS Code with this project open
    • This launches a new Extension Development Host window with the extension loaded
  5. To install for regular use:

    • Package the extension: vsce package
    • Install the generated .vsix file: code --install-extension import-file-creator-0.0.1.vsix

Usage

The extension works automatically:

  1. Write an import statement for a file that doesn't exist yet:

    import { Button } from './components/Button';
  2. Save the file

  3. The extension will detect that ./components/Button.js (or similar) doesn't exist and show a notification:

    File not found: components/Button.js. Create it?
    
  4. Click "Create File" to generate the file with an appropriate template

  5. The file will be created and opened for editing

Supported File Types

The extension creates appropriate templates for:

  • React components (.jsx, .tsx)
  • TypeScript files (.ts)
  • JavaScript modules (.js)
  • CSS and SCSS files (.css, .scss, .module.css)
  • JSON files (.json)
  • Vue components (.vue)

Configuration

Currently, the extension works with minimal configuration. Future versions may include settings for customizing templates.

Known Limitations

  • Node modules and absolute imports are not processed
  • Some complex import path formats might not be correctly resolved
  • The extension currently uses predefined templates rather than user-customizable ones

Contributing

Contributions are welcome! This extension addresses a specific pain point in development workflows and can be expanded to support more file types and customization options.

License

MIT


Note: This extension is not officially affiliated with Cursor or VSCode.

// Import Path File Creator Extension
// Detects missing files from import statements and offers to create them
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
export function activate(context: vscode.ExtensionContext) {
console.log('Import Path File Creator extension is now active');
// Register a document change listener
const changeDisposable = vscode.workspace.onDidChangeTextDocument(event => {
// Only process when the document is saved
if (event.document.isDirty) {
return;
}
analyzeImports(event.document);
});
// Also check on document save
const saveDisposable = vscode.workspace.onDidSaveTextDocument(document => {
analyzeImports(document);
});
// Register a command to create the missing file
const createFileDisposable = vscode.commands.registerCommand(
'importFileCreator.createFile',
(filePath: string, fileType: string) => {
createMissingFile(filePath, fileType);
}
);
context.subscriptions.push(changeDisposable, saveDisposable, createFileDisposable);
}
// Analyze imports in a document to find missing files
async function analyzeImports(document: vscode.TextDocument) {
// Skip if not a code file
if (!isCodeFile(document.fileName)) {
return;
}
const text = document.getText();
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri)?.uri.fsPath;
if (!workspaceFolder) {
return;
}
const documentDir = path.dirname(document.fileName);
// Find import statements
// Common patterns:
// import X from 'path';
// import { X } from 'path';
// import * as X from 'path';
// require('path');
// CSS imports: @import 'path';
const importRegexes = [
/import\s+(?:.+\s+from\s+)?['"]([^'"]+)['"]/g, // ES6 imports
/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g, // CommonJS require
/@import\s+['"]([^'"]+)['"]/g, // CSS imports
];
const missingImports = new Set<string>();
const importPathToType = new Map<string, string>();
for (const regex of importRegexes) {
let match;
while ((match = regex.exec(text)) !== null) {
const importPath = match[1];
// Skip node_modules and absolute imports
if (importPath.startsWith('http') ||
!importPath.startsWith('.') ||
importPath.includes('node_modules')) {
continue;
}
// Resolve the full path
let resolvedPath = resolveImportPath(importPath, documentDir);
// If the file doesn't exist, add it to missing imports
if (resolvedPath && !fs.existsSync(resolvedPath)) {
const fileType = determineFileType(resolvedPath, document.fileName);
missingImports.add(resolvedPath);
importPathToType.set(resolvedPath, fileType);
}
}
}
// If we found missing imports, show notifications
for (const missingImport of missingImports) {
const relativePath = path.relative(workspaceFolder, missingImport);
const fileType = importPathToType.get(missingImport) || 'Unknown';
vscode.window.showInformationMessage(
`File not found: ${relativePath}. Create it?`,
'Create File'
).then(selection => {
if (selection === 'Create File') {
vscode.commands.executeCommand(
'importFileCreator.createFile',
missingImport,
fileType
);
}
});
}
}
// Resolve the import path to a full file path
function resolveImportPath(importPath: string, documentDir: string): string | null {
let resolvedPath = path.resolve(documentDir, importPath);
// If the path doesn't have an extension, try to determine it
if (!path.extname(resolvedPath)) {
const extensions = ['.js', '.jsx', '.ts', '.tsx', '.css', '.scss', '.json', '.vue'];
// Check if the path exists as a directory and might have an index file
if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isDirectory()) {
for (const ext of extensions) {
const indexPath = path.join(resolvedPath, `index${ext}`);
if (fs.existsSync(indexPath)) {
return indexPath;
}
}
// Directory exists but no index file found, use index.js as default
return path.join(resolvedPath, 'index.js');
}
// Try common extensions
for (const ext of extensions) {
const pathWithExt = `${resolvedPath}${ext}`;
if (fs.existsSync(pathWithExt)) {
return pathWithExt;
}
}
// Default to adding .js if no other extension was found
return `${resolvedPath}.js`;
}
return resolvedPath;
}
// Determine the file type based on extension or importing file
function determineFileType(filePath: string, sourceFile: string): string {
const ext = path.extname(filePath);
// Map extensions to file types
switch (ext) {
case '.js':
return 'JavaScript';
case '.jsx':
return 'React JSX';
case '.ts':
return 'TypeScript';
case '.tsx':
return 'React TSX';
case '.css':
return 'CSS';
case '.scss':
return 'SCSS';
case '.less':
return 'LESS';
case '.module.css':
case '.module.scss':
return 'CSS Module';
case '.json':
return 'JSON';
case '.vue':
return 'Vue';
default:
// If importing from a React file, assume it's React-related
if (sourceFile.endsWith('.jsx') || sourceFile.endsWith('.tsx')) {
return 'React Component';
}
// If importing from a TS file, assume it's TS
if (sourceFile.endsWith('.ts')) {
return 'TypeScript';
}
return 'Unknown';
}
}
// Check if the file is a code file we should process
function isCodeFile(fileName: string): boolean {
const codeExtensions = [
'.js', '.jsx', '.ts', '.tsx',
'.vue', '.svelte',
'.css', '.scss', '.less',
'.php', '.py', '.rb',
'.go', '.java', '.rs'
];
return codeExtensions.some(ext => fileName.endsWith(ext));
}
// Create the missing file with appropriate template
async function createMissingFile(filePath: string, fileType: string) {
try {
// Ensure the directory exists
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
// Get appropriate template for the file type
const template = getFileTemplate(filePath, fileType);
// Write the file
fs.writeFileSync(filePath, template);
// Open the newly created file
const document = await vscode.workspace.openTextDocument(filePath);
vscode.window.showTextDocument(document);
vscode.window.showInformationMessage(`Successfully created ${path.basename(filePath)}`);
} catch (error) {
vscode.window.showErrorMessage(`Failed to create file: ${error}`);
}
}
// Get a template based on file type
function getFileTemplate(filePath: string, fileType: string): string {
const fileName = path.basename(filePath);
const fileNameWithoutExt = fileName.split('.')[0];
switch (fileType) {
case 'React Component':
case 'React JSX':
case 'React TSX':
return `import React from 'react';\n\nconst ${fileNameWithoutExt} = () => {\n return (\n <div>\n ${fileNameWithoutExt} Component\n </div>\n );\n};\n\nexport default ${fileNameWithoutExt};\n`;
case 'CSS Module':
case 'CSS':
return `/* ${fileName} styles */\n\n`;
case 'SCSS':
case 'LESS':
return `/* ${fileName} styles */\n\n`;
case 'TypeScript':
if (fileNameWithoutExt === 'types' || fileNameWithoutExt === 'interfaces') {
return `// ${fileName} type definitions\n\nexport interface Example {\n id: string;\n name: string;\n}\n`;
}
return `// ${fileName}\n\nexport const example = () => {\n console.log('Hello from ${fileNameWithoutExt}');\n};\n`;
case 'JavaScript':
return `// ${fileName}\n\nexport const example = () => {\n console.log('Hello from ${fileNameWithoutExt}');\n};\n`;
case 'JSON':
return `{\n "name": "${fileNameWithoutExt}",\n "version": "1.0.0"\n}\n`;
case 'Vue':
return `<template>\n <div>\n ${fileNameWithoutExt} Component\n </div>\n</template>\n\n<script>\nexport default {\n name: '${fileNameWithoutExt}',\n data() {\n return {};\n }\n};\n</script>\n\n<style scoped>\n\n</style>\n`;
default:
return `// ${fileName}\n`;
}
}
export function deactivate() {
console.log('Import Path File Creator extension is now deactivated');
}
I'll check the Cursor forum thread you mentioned to understand the feature request for suggesting file creation based on import paths, and then modify the extension accordingly.
Based on the search results, I understand that the feature request is about suggesting file creation when import paths refer to files that don't exist yet. The forum post mentions wanting Cursor to detect when a file referenced in an import statement doesn't exist and prompt "File X not found. Create it?"
I'll create a VS Code extension that detects missing imported files and offers to create them automatically.
# Import Path File Creator Extension - Installation Instructions
This extension automatically detects when you're importing files that don't exist yet and offers to create them with appropriate templates - exactly what was requested in that Cursor forum thread about suggesting file creation from import paths.
## Quick Installation Steps:
1. **Create a new VS Code extension project**:
```bash
npm init vscode-extension
# Choose TypeScript when prompted
```
2. **Replace the files with those from the artifacts**:
- Replace `src/extension.ts` with the "Import Path File Creator Extension" artifact
- Replace `package.json` with the "package.json for Import Path File Creator" artifact
3. **Install dependencies and build**:
```bash
npm install
npm run compile
```
4. **Test the extension**:
- Press F5 in VS Code/Cursor to launch with the extension
- Try writing an import statement for a non-existent file like:
```js
import styles from './About.module.scss'
```
- Save the file
- You'll get a notification offering to create the missing file
5. **Package for distribution** (optional):
```bash
npm install -g vsce
vsce package
code --install-extension import-file-creator-0.0.1.vsix
```
## How It Works
The extension:
1. Monitors your code files for import statements
2. Detects when imported files don't exist
3. Offers to create them with appropriate templates based on file type
4. Automatically creates any necessary directories
5. Opens the newly created file for editing
This should solve the exact problem mentioned in the forum thread where users want Cursor to detect missing imported files and offer to create them.
{
"name": "import-file-creator",
"displayName": "Import File Creator",
"description": "Automatically detect missing import files and offer to create them",
"version": "0.0.1",
"engines": {
"vscode": "^1.60.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "importFileCreator.createFile",
"title": "Create Missing Import File"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/vscode": "^1.60.0",
"@types/node": "^16.11.7",
"typescript": "^4.5.5"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment