Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Smart Duplicate FileNew to Visual Studio Code? Get it now.
Smart Duplicate File

Smart Duplicate File

Frederik Hudák

| (0) | Free
| Sponsor
File duplication utility
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Smart Duplicate File

Duplicate files intelligently - automatically rename classes, functions, and identifiers to match the new filename. I guess that doesn't make it a duplicate anymore. But when do you ever need the same exact thing twice?

Features

  • Customizable prefixes/suffixes FirstController → SecondController will replace not just the class name, but also all occurrences of First to Second

  • Smart word boundaries Short names like Id won't accidentally match inside words like valid

  • Plural handling Renaming Child → Person correctly transforms Children → People. Supports pluralization via conventions and many irregular forms (this does not mean complete coverage of English though)

  • Encoding preservation Automatically detects and preserves file encoding (UTF-8, UTF-16, etc.) and BOM markers

  • Easily extensible test suite to verify behavior

Supported Naming Conventions

Automatically handles variants, even multiple conventions in the same file

  • PascalCase
  • camelCase
  • snake_case
  • kebab-case
  • space separated
  • Title Case
  • SCREAMING_SNAKE_CASE

Examples

C# Class

Original: BankController.cs

using System.Collections.Generic;

public class Bank
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class BankController : IBaseController<Bank>
{
    private readonly DbContext _context;
    
    public BankController(DbContext context)
    {
        _context = context;
    }
    
    public Bank GetById(int id)
    {
        return _context.Set<Bank>().Find(id);
    }
    
    public IEnumerable<Bank> GetAll()
    {
        return _context.Set<Bank>().ToList();
    }
    
    public void Create(Bank bank)
    {
        _context.Set<Bank>().Add(bank);
        _context.SaveChanges();
    }
    
    public void Update(Bank bank)
    {
        _context.Set<Bank>().Update(bank);
        _context.SaveChanges();
    }
    
    public void Delete(Bank bank)
    {
        _context.Set<Bank>().Remove(bank);
        _context.SaveChanges();
    }
}

// BankController handles all bank-related operations
// Banks are stored in the database

After duplicating to ProductController.cs

using System.Collections.Generic;

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ProductController : IBaseController<Product>
{
    private readonly DbContext _context;
    
    public ProductController(DbContext context)
    {
        _context = context;
    }
    
    public Product GetById(int id)
    {
        return _context.Set<Product>().Find(id);
    }
    
    public IEnumerable<Product> GetAll()
    {
        return _context.Set<Product>().ToList();
    }
    
    public void Create(Product product)
    {
        _context.Set<Product>().Add(product);
        _context.SaveChanges();
    }
    
    public void Update(Product product)
    {
        _context.Set<Product>().Update(product);
        _context.SaveChanges();
    }
    
    public void Delete(Product product)
    {
        _context.Set<Product>().Remove(product);
        _context.SaveChanges();
    }
}

// ProductController handles all product-related operations
// Products are stored in the database

TypeScript React Component

Original: user-profile.tsx

export interface UserProfileProps {
    userId: string;
}

export const UserProfile: React.FC<UserProfileProps> = ({ userId }) => {
    return <div className="user-profile">Profile for {userId}</div>;
};

export default UserProfile;

After duplicating to admin-profile.tsx

export interface AdminProfileProps {
    userId: string;
}

export const AdminProfile: React.FC<AdminProfileProps> = ({ userId }) => {
    return <div className="admin-profile">Profile for {userId}</div>;
};

export default AdminProfile;

Intelligently converted:

  • user-profile (kebab-case) → admin-profile
  • UserProfile (PascalCase) → AdminProfile
  • UserProfileProps → AdminProfileProps
Python Class

Original: data_validator.py

class DataValidator:
    def __init__(self):
        self.name = "DataValidator"
    
    def validate(self, data):
        """DataValidator implementation"""
        return True

# creates the data validator
def create_data_validator():
    return DataValidator()

After duplicating to schema_validator.py

class SchemaValidator:
    def __init__(self):
        self.name = "SchemaValidator"
    
    def validate(self, data):
        """SchemaValidator implementation"""
        return True

# creates the schema validator
def create_schema_validator():
    return SchemaValidator()

All references including snake_case function names and comments updated automatically.

Usage

Quick Start

  1. Right-click on a file in the Explorer (or in the editor)
  2. Select Smart Duplicate (Ctrl+K Ctrl+D)
  3. Enter the new filename
  4. Review the diff

Access Points

  • Explorer context menu - Right-click any file
  • Editor context menu - Right-click in an open file
  • Command Palette - Search for "Smart Duplicate"

Settings

Setting Default Description
smartDuplicateFile.postDuplicationAction compareWithOriginal Action after duplicating: openFile, compareWithOriginal (diff view), or openSideBySide
smartDuplicateFile.strippablePrefixes ["use", "get", "set", "is", "has"] Prefixes to strip when replacing (e.g., useBankAccount → useCurrency replaces BankAccount with Currency)
smartDuplicateFile.strippableSuffixes ["Store", "Service", ...] Suffixes to strip when replacing (e.g., UserStore → ProductStore replaces User with Product)

Access settings via Settings (Ctrl+,) → search "Smart Duplicate File".

Tips

  • Use the default diff view to review changes before saving
  • Update strippablePrefixes and strippableSuffixes with ones common in your codebase
  • Works best with consistent naming conventions

💡 A note on clean code: Many replacements this extension performs (like updating comments that repeat class names) wouldn't be necessary with cleaner code practices. Comments like // creates the user validator or """UserValidator implementation""" are often redundant - the code should be self-documenting. If you find yourself needing extensive comment replacements, consider whether they add value in the first place.

Contributing

Contributions are welcome! Here's how to get started:

Development Setup

git clone https://github.com/FreHu/vscode-duplicate-plus-plus.git
cd vscode-duplicate-plus-plus
npm install

Press F5 in VS Code to launch the Extension Development Host. This may show some errors because there are invalid .ts files used as test data. They can be ignored.

Running Tests

npm test

Test Structure

Each test is composed of an input/output file pair in src/test/fixtures/:

To add a new test case:

  1. Create your-test-name.in.ext with the input content
  2. Create your-test-name.out.ext with the expected output
  3. Add the test case to src/test/extension.test.ts

Known Issues

None, but this simply can't cover everything. If you feel like you found

  • a replacement which seems doable but currently isn't handled
  • a replacement which shouldn't occur

Then open an issue and include a test case.

Release Notes

0.0.1

Initial release:

  • Intelligent multi-convention filename replacement
  • Configurable prefix/suffix stripping
  • Diff view for reviewing changes
  • Context menu integration (Explorer & Editor)
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft