Skip to content

Resolving Case Ambiguity

When renaming identifiers, Renamify sometimes encounters ambiguous cases where the same text could belong to multiple case styles. This guide explains how Renamify intelligently resolves these ambiguities.

An identifier is ambiguous when it could validly belong to multiple case styles. For example:

  • api - all lowercase, could be replaced with snake_case, camelCase, or kebab-case
  • ID - all uppercase, could be replaced with PascalCase with an acronym, or SCREAMING_SNAKE_CASE

Renamify uses a sophisticated multi-level approach to resolve ambiguities, trying each strategy in order until a clear answer is found:

For known programming languages, Renamify applies language-specific heuristics based on syntactic context. The system supports over 30 file extensions with intelligent context-aware suggestions.

Supported Languages:

  • Ruby (.rb, .rake, .gemspec): Classes/modules → PascalCase, methods → snake_case, constants → SCREAMING_SNAKE
  • Python (.py, .pyw, .pyi): Classes → PascalCase, functions/decorators → snake_case, constants → SCREAMING_SNAKE
  • JavaScript/TypeScript (.js, .jsx, .ts, .tsx, .mjs, .cjs): Classes/interfaces → PascalCase, variables/functions → camelCase, constants → SCREAMING_SNAKE
  • Go (.go): Exported types/functions → PascalCase, unexported → camelCase, packages → lowercase
  • Rust (.rs): Types → PascalCase, functions/modules → snake_case, constants → SCREAMING_SNAKE, macros → snake_case
  • Java/Kotlin (.java, .kt, .kts): Classes → PascalCase, methods/fields → camelCase, constants → SCREAMING_SNAKE
  • C/C++ (.c, .cpp, .cc, .h, .hpp): Classes/structs → PascalCase or snake_case, macros → SCREAMING_SNAKE
  • Shell Scripts (.sh, .bash, .zsh): Environment variables → SCREAMING_SNAKE, functions/locals → snake_case
  • Web Technologies (HTML, CSS, YAML, JSON): Attributes/classes → kebab-case, config keys → snake_case or camelCase

Ruby Example:

# "User" after "class" -> PascalCase expected
class User
end
# "process_data" after "def" -> snake_case expected
def process_data
end
# "MAX_SIZE" in constant context -> SCREAMING_SNAKE expected
MAX_SIZE = 100

Python Example:

def get_user(): # snake_case expected after "def"
pass
class UserModel: # PascalCase expected after "class"
pass
@decorator_name # snake_case expected after "@"
def method():
pass

JavaScript Example:

class UserController {} // PascalCase after "class"
const userName = ''; // camelCase after "const"
const MAX_RETRIES = 3; // SCREAMING_SNAKE in all-caps context
process.env.NODE_ENV; // SCREAMING_SNAKE for env vars


Next, Renamify analyzes the predominant case style in your file. If a file uses mostly camelCase and the match starts with a lowercase letter, ambiguous identifiers will be resolved as camelCase.

Example:

// File with predominantly camelCase
function getUserName() { ... }
function setUserEmail() { ... }
const userId = 123;
// If we replace "api" with "api_wrapper", these instances are likely camelCase:
const api = new api();
// =====> const apiWrapper = new apiWrapper();

If file-wide analysis isn’t conclusive, Renamify looks at the context within that line (e.g. const, function, class, etc.) and searches for other examples in the codebase that have the same file extension. (This operation is performed only when needed and cached.)

When no methods can provide a clear answer, Renamify defaults to the case style of your replacement string.

Example:

Terminal window
# Replacing "config" with "settings_data" (snake_case)
# Found: .config (ambiguous)
# Result: .settings_data (uses snake_case from replacement)
# Replacing "config" with "settingsData" (camelCase)
# Found: .config (ambiguous)
# Result: .settingsData (uses camelCase from replacement)

Renamify never changes the fundamental character properties of a match:

  • If a match starts with lowercase (like api), it can only be resolved to styles that also start with lowercase (snake_case, camelCase, kebab-case, lower)
  • If a match starts with uppercase (like Api), it can only be resolved to styles that also start with uppercase (PascalCase, Train-Case)
{
"name": "myapp",
"version": "1.0.0"
}

With few identifiers to analyze, Renamify falls back to the replacement string’s style:

  • Replacing myapp with new_name → uses snake_case
  • Replacing myapp with newName → uses camelCase
class UserController {
private userId: string;
getUserData() { ... }
updateUserProfile() { ... }
}

The file predominantly uses camelCase, so:

  • .config would become .configData (camelCase) even if the replacement string is config_data

When a file has no dominant style, Renamify defaults to the replacement string’s style for maximum predictability.

You can always be explicit about the case styles you want to include or exclude:

Terminal window
# Force specific styles only
renamify plan "api" "application" --only-styles snake,kebab
# Ignore ambiguous matches entirely
renamify plan "api" "application" --ignore-ambiguous
  1. Be consistent - Files with consistent case styles get better ambiguity resolution
  2. Use explicit styles - When in doubt, use --only-styles to be explicit
  3. Preview first - Always preview changes before applying them
  4. Test incrementally - Apply changes to a subset of files first

The ambiguity resolution system:

  • Only activates for truly ambiguous cases
  • Respects character constraints (uppercase/lowercase)
  • Caches file analysis for performance
  • Can be disabled with --ignore-ambiguous

This intelligent system ensures that Renamify makes sensible decisions most of the time, while still giving you full control when needed.