mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
Ref-name inputs only validated after the fact, so a space typed or pasted into a branch name showed "Branch name contains invalid characters" and disabled Create. Branch-name fields (New Branch, from a revision and in several repositories, Rename Branch, New Worktree, GitHub New Remote Branch) now clean the name while typing: forbidden characters are dropped and whitespace becomes '-', without stacking separators, keeping the caret in place. Shared via src/platform/gitRefName.ts and the useSanitizedField hook in src/ui. Closes #1553 Co-authored-by: jaw52 <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
/** Ports IntelliJ's `GitRefNameValidator.cleanUpBranchNameOnTyping` (git4idea). */
|
|
|
|
/** IntelliJ's advanced setting `git.branch.cleanup.symbol` (default `-`). */
|
|
export const BRANCH_CLEANUP_SYMBOL = "-";
|
|
|
|
// Characters and sequences git forbids that cannot be repaired by substitution are dropped.
|
|
const DROP = /^\.|^-|^\/|[~:^?*"[\\]+|(?:@\{)+|\/(?=\/)|(?:\.(?=\.))+|\.(?=\/)/g;
|
|
// IntelliJ drops a dot after a slash with a lookbehind, which pre-16.4 WebKit cannot parse.
|
|
const DOT_AFTER_SLASH = /\/\./g;
|
|
// A run of whitespace / control characters becomes one separator. It also absorbs separators
|
|
// mixed into or next to it, so pressing Space again after the substituted one doesn't stack them (IntelliJ
|
|
// collapses only spaces typed in one go).
|
|
const SEPARATOR = BRANCH_CLEANUP_SYMBOL.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
const REPLACE = new RegExp(`(?:${SEPARATOR}|[ \\p{Cc}])*[ \\p{Cc}](?:${SEPARATOR}|[ \\p{Cc}])*`, "gu");
|
|
|
|
function cleanOnce(name: string): string {
|
|
return name.replace(DROP, "").replace(DOT_AFTER_SLASH, "/").replace(REPLACE, BRANCH_CLEANUP_SYMBOL);
|
|
}
|
|
|
|
/**
|
|
* Makes `name` typable as a branch name: forbidden characters are dropped and spaces become the
|
|
* cleanup symbol, so a space never reaches the validator. Runs to a fixed point because the
|
|
* substitution can itself form a forbidden start (" x" → "-x" → "x").
|
|
*/
|
|
export function cleanUpBranchNameOnTyping(name: string): string {
|
|
let cleaned = name;
|
|
for (;;) {
|
|
const next = cleanOnce(cleaned);
|
|
if (next === cleaned) return cleaned;
|
|
cleaned = next;
|
|
}
|
|
}
|