-
Notifications
You must be signed in to change notification settings - Fork 338
/
Copy pathutils.ts
127 lines (118 loc) · 3.6 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { PathExt } from '@jupyterlab/coreutils';
import { CommandRegistry } from '@lumino/commands';
import { CommandArguments } from './commandsAndMenu';
import { ContextCommandIDs, Git } from './tokens';
/** Get the filename from a path */
export function extractFilename(path: string): string {
if (path[path.length - 1] === '/') {
return path;
} else {
return PathExt.basename(path);
}
}
/**
* Wrap mouse event handler to stop event propagation
* @param fn Mouse event handler
* @returns Mouse event handler that stops event from propagating
*/
export function stopPropagationWrapper(
fn: (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
): (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void {
return (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event?.stopPropagation();
fn(event);
};
}
export function decodeStage(x: string, y: string): Git.Status {
/**
* All combinations of statuses for merge conflicts
* @see https://git-scm.com/docs/git-status#_short_format
*/
const unmergedCombinations: Record<string, string[]> = {
D: ['D', 'U'],
A: ['U', 'A'],
U: ['D', 'A', 'U']
};
// If the file has a merge conflict
if ((unmergedCombinations[x] ?? []).includes(y)) {
return 'unmerged';
}
// If file is untracked
if (x === '?' && y === '?') {
return 'untracked';
} else {
// If file is staged
if (x !== ' ') {
return y !== ' ' ? 'partially-staged' : 'staged';
}
// If file is unstaged but tracked
if (y !== ' ') {
return 'unstaged';
}
}
return null;
}
/**
* Returns a promise which resolves after a specified duration.
*
* @param ms - duration (in milliseconds)
* @returns a promise
*/
export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* A callback function to display a file diff between two commits.
* @param commands the command registry.
* @returns a callback function to display a file diff.
*/
export const openFileDiff =
(commands: CommandRegistry) =>
/**
* A callback function to display a file diff between two commits.
*
* @param commit Commit data.
* @param previousCommit Previous commit data to display the diff against. If not specified, the diff will be against the preceding commit.
*
* @returns A callback function.
*/
(commit: Git.ISingleCommitInfo, previousCommit?: Git.ISingleCommitInfo) =>
/**
* Returns a callback to be invoked on click to display a file diff.
*
* @param filePath file path.
* @param isText indicates whether the file supports displaying a diff.
* @param previousFilePath when file has been relocated.
* @returns callback.
*/
(filePath: string, isText: boolean, previousFilePath?: string) =>
/**
* Callback invoked upon clicking to display a file diff.
*
* @param event - event object
*/
async (
event?: React.MouseEvent<HTMLLIElement, MouseEvent>
): Promise<void> => {
// Prevent the commit component from being collapsed:
event?.stopPropagation();
if (isText) {
try {
commands.execute(ContextCommandIDs.gitFileDiff, {
files: [
{
filePath,
previousFilePath,
isText,
context: {
previousRef: previousCommit?.commit ?? commit.pre_commits[0], // not sure
currentRef: commit.commit
}
}
]
} as CommandArguments.IGitFileDiff as any);
} catch (err) {
console.error(`Failed to open diff view for ${filePath}.\n${err}`);
}
}
};