-
Notifications
You must be signed in to change notification settings - Fork 0
/
extension.ts
116 lines (87 loc) · 4.4 KB
/
extension.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
import * as vscode from "vscode";
const EXTN_QUALIFIER = 'go-to-character-position';
const COMMANDS = Object.seal({
go_to_character_position: `${EXTN_QUALIFIER }.go-to-character-position`
})
let cachedInput : any = undefined;
let statusbar : vscode.StatusBarItem;
let indexing: string = getEnumConfiguration('defaultIndex', 'zero based', ['zero based', 'one based']);
/**
* @param {vscode.ExtensionContext} context
*/
export function activate(context: vscode.ExtensionContext) {
console.log('"go-to-character-position" is active');
context.subscriptions.push(
statusbar,
vscode.window.onDidChangeTextEditorSelection(updateStatusBarItem),
vscode.workspace.onDidChangeConfiguration((e: vscode.ConfigurationChangeEvent) => {
if (e.affectsConfiguration(`${EXTN_QUALIFIER}.defaultIndex`))
indexing = getEnumConfiguration('defaultIndex', 'zero based', ['zero based', 'one based']);
if (e.affectsConfiguration(`${EXTN_QUALIFIER}.statusbar`))
updateStatusBarItemPriority(getConfiguration(`statusbar.priority`, 101));
}),
vscode.commands.registerTextEditorCommand(COMMANDS.go_to_character_position, async function (editor) {
const indexing = getEnumConfiguration('defaultIndex', 'zero based', ['zero based', 'one based']);
const input = await vscode.window.showInputBox({
ignoreFocusOut: true,
prompt: `Your current index setting is ${indexing} and there are ${new Intl.NumberFormat().format(editor.document.getText().length)} characters in this text body`,
title: "Jump to an absolute character index in the active editor",
value: cachedInput === undefined ? '' : cachedInput,
validateInput: (value) => {
if (!value.match(/^\d+$/m))
return "Invalid input. Please enter a valid positive whole number"
return null;
}
});
if (input === undefined) return
let index = clamp(+input, 0);
cachedInput = index;
if (indexing === 'one based') index = clamp(index - 1, 0)
let target = editor.document.positionAt(index);
target = editor.document.validatePosition(target);
editor.revealRange(new vscode.Range(target, target), getRevealType());
editor.selection = new vscode.Selection(target, target);
})
);
updateStatusBarItemPriority(101);
}
// this method is called when your extension is deactivated
export function deactivate() { }
function getRevealType() {
const revealType = getEnumConfiguration('revealType', 'top', ['top', 'center', 'default', 'centerifoutsidetheviewport']);
switch (revealType) {
case 'default':
return vscode.TextEditorRevealType.Default
case 'center':
return vscode.TextEditorRevealType.InCenter
case 'centerifoutsidetheviewport':
return vscode.TextEditorRevealType.InCenterIfOutsideViewport
default:
return vscode.TextEditorRevealType.AtTop
}
}
function getConfiguration(identifier: string, defalt: any): any {
return vscode.workspace.getConfiguration(EXTN_QUALIFIER).get(identifier, defalt);
}
function getEnumConfiguration(identifier: string, defaultConfig: string, possibles : string[] = []) {
let enumType = vscode.workspace.getConfiguration(EXTN_QUALIFIER).get(identifier) as string;
enumType = possibles.includes(enumType.toLowerCase()) ? enumType.toLowerCase() : defaultConfig.toLowerCase();
return enumType
}
function clamp(val: any, min: any, max = Infinity) {
if (val < min) return min;
if (val > max) return max;
return val
}
function updateStatusBarItemPriority(priority: number) {
if (statusbar) statusbar.dispose();
statusbar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, priority);
statusbar.name = '↷ Go To Character Index';
statusbar.tooltip = `↷ Current Index${indexing === 'one based' ? '¹' : 'º'}`;
statusbar.command = COMMANDS.go_to_character_position;
statusbar.show();
}
function updateStatusBarItem(e: vscode.TextEditorSelectionChangeEvent) {
const index = e.textEditor.document.offsetAt(e.textEditor.selection.active) + +(indexing === 'one based');
statusbar.text = `↷ ${index.toLocaleString()}${indexing === 'one based' ? '¹' : 'º'}`;
}