Skip to content

Commit 6c63e17

Browse files
authored
Fix types (#205)
* fix types * fix search register * resolve more cases of any type * remove explicit uses of any
1 parent a1d9b3d commit 6c63e17

File tree

8 files changed

+684
-371
lines changed

8 files changed

+684
-371
lines changed

dev/index.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { highlightActiveLine, keymap, Decoration, DecorationSet,
33
ViewPlugin, ViewUpdate, WidgetType, drawSelection } from '@codemirror/view';
44
import { javascript } from '@codemirror/lang-javascript';
55
import { xml } from '@codemirror/lang-xml';
6-
import { Vim, vim } from "../src/index"
6+
import { Vim, vim } from "../src/index" // "@replit/codemirror-vim"
77

88
import * as commands from "@codemirror/commands";
99
import { Annotation, Compartment, EditorState, Extension, Transaction, Range } from '@codemirror/state';
@@ -25,7 +25,8 @@ new EditorView({
2525
2626
`;
2727

28-
function addOption(name, description?, onclick?) {
28+
function addOption(name: "wrap"|"html"|"status"|"jj"|"split"|"readOnly",
29+
description?: string, onclick?: (value: boolean) => void) {
2930
let checkbox = document.createElement("input");
3031
checkbox.type = "checkbox";
3132
checkbox.id = name;
@@ -49,16 +50,16 @@ class TestWidget extends WidgetType {
4950
constructor(private side: number) {
5051
super();
5152
}
52-
eq(other) {
53-
return (true);
53+
override eq(other: TestWidget) {
54+
return other == this;
5455
}
5556
toDOM() {
5657
const wrapper = document.createElement('span');
5758
wrapper.textContent = " widget" + this.side + " "
5859
wrapper.style.opacity = '0.4';
5960
return wrapper;
6061
}
61-
ignoreEvent() {
62+
override ignoreEvent() {
6263
return false;
6364
}
6465
}
@@ -73,7 +74,7 @@ function widgets(view: EditorView) {
7374
})
7475
widgets.push(deco.range(200 + 10 * i))
7576
}
76-
console.log(widgets)
77+
console.log(widgets, view)
7778
return Decoration.set(widgets)
7879
}
7980

@@ -93,6 +94,7 @@ const testWidgetPlugin = ViewPlugin.fromClass(class {
9394

9495
eventHandlers: {
9596
mousedown: (e, view) => {
97+
console.log("mousedown", e, view)
9698
}
9799
}
98100
})
@@ -117,10 +119,12 @@ var options = {
117119

118120

119121
Vim.defineOption('wrap', false, 'boolean', null, function(val, cm) {
122+
if (!cm) console.log("should set global option");
120123
if (val == undefined) return options.wrap;
121-
var checkbox = document.getElementById("wrap");
124+
var checkbox = document.getElementById("wrap") as HTMLInputElement;
122125
if (checkbox) {
123126
checkbox.checked = val;
127+
//@ts-ignore
124128
checkbox.onclick();
125129
}
126130
});
@@ -166,21 +170,22 @@ var defaultExtensions = [
166170
]),
167171
]
168172

169-
function saveTab(name) {
173+
function saveTab(name: string) {
170174
return EditorView.updateListener.of((v) => {
171175
tabs[name] = v.state;
172176
})
173177
}
174178

175-
var tabs = {
179+
180+
var tabs: Record<string, EditorState> = {
176181
js: EditorState.create({
177182
doc: doc,
178183
extensions: [...defaultExtensions, javascript(), saveTab("js")]
179184
}),
180185
html: EditorState.create({
181186
doc: document.documentElement.outerHTML,
182187
extensions: [...defaultExtensions, testWidgetPlugin, xml(), saveTab("html")]
183-
})
188+
}),
184189
}
185190

186191
function updateView() {
@@ -204,17 +209,25 @@ function updateView() {
204209
})
205210
}
206211

212+
declare global {
213+
interface Window {
214+
blinkRate?: number;
215+
}
216+
}
217+
207218
function selectTab(tab: string) {
208-
if (view) view.setState(tabs[tab])
209-
if (view2) view2.setState(tabs[tab])
219+
let state = tabs[tab];
220+
if (!state) return;
221+
if (view) view.setState(state)
222+
if (view2) view2.setState(state)
210223
addLogListeners();
211224
}
212225

213226
Vim.defineEx("tabnext", "tabn", () => {
214-
tabs["scratch"] = EditorState.create({
227+
tabs.scratch = EditorState.create({
215228
doc: "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
216229
extensions: [defaultExtensions, saveTab("scratch")],
217-
})
230+
});
218231
selectTab("scratch")
219232
});
220233

@@ -304,7 +317,7 @@ updateView()
304317
// save and restor search history
305318

306319

307-
function saveHistory(name) {
320+
function saveHistory(name: "exCommandHistoryController"|"searchHistoryController") {
308321
var controller = Vim.getVimGlobalState_()[name];
309322
var json = JSON.stringify(controller);
310323
if (json.length > 10000) {
@@ -315,11 +328,11 @@ function saveHistory(name) {
315328
}
316329
localStorage[name] = json;
317330
}
318-
function restoreHistory(name) {
331+
function restoreHistory(name: "exCommandHistoryController"|"searchHistoryController") {
319332
try {
320333
var json = JSON.parse(localStorage[name]);
321334
var controller = Vim.getVimGlobalState_()[name];
322-
controller.historyBuffer = json.historyBuffer.filter(x => typeof x == "string" && x)
335+
controller.historyBuffer = json.historyBuffer.filter((x: unknown) => typeof x == "string" && x)
323336
controller.iterator = Math.min(parseInt(json.iterator) || Infinity, controller.historyBuffer.length)
324337
} catch(e) {
325338

@@ -333,3 +346,7 @@ window.onunload = function() {
333346
saveHistory('exCommandHistoryController');
334347
saveHistory('searchHistoryController');
335348
}
349+
350+
Vim.defineEx("write", "w", (cm) => {
351+
console.log("called", cm);
352+
})

package.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
"scripts": {
1010
"dev": "vite ./dev",
1111
"test": "cm-runtests",
12-
"static": "tsc --noEmit",
13-
"testAll": "yarn run static && yarn run test && cd dev/cm5 && yarn run buildAndTest",
14-
"build": "cm-buildhelper src/index.ts && node scripts/addVersion.cjs",
12+
"build-types": "rm -rf out && tsc && dts-bundle-generator out/index.ts -o dist/index.d.ts && cp dist/index.d.ts dist/index.d.cts",
13+
"testAll": "yarn run build-test-package && yarn run test && cd dev/cm5 && yarn run buildAndTest",
14+
"build": "cm-buildhelper src/index.ts && node scripts/addVersion.cjs && npm run build-types",
1515
"publish": "yarn run build && npm publish",
16+
"build-test-package": "bash ./scripts/build-test-package.sh",
1617
"prepare": "yarn run build"
1718
},
1819
"keywords": [
@@ -42,9 +43,14 @@
4243
"@codemirror/lang-xml": "^6.0.0",
4344
"@codemirror/language": "^6.1.0",
4445
"codemirror": "6.0.1",
45-
"typescript": "^5.0.2",
46-
"vite": "^2.9.6"
46+
"dts-bundle-generator": "^9.5.1",
47+
"typescript": "^5.7.3",
48+
"vite": "^6.1.0"
4749
},
50+
"files": [
51+
"dist",
52+
"README.md"
53+
],
4854
"repository": {
4955
"type": "git",
5056
"url": "https://github.com/replit/codemirror-vim.git"

scripts/build-test-package.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/bash
2+
set -euxo pipefail
3+
4+
# Navigate to the repository root
5+
cd "$(dirname "$0")/.."
6+
ROOT="$(pwd)"
7+
8+
# npm pack the repository
9+
rm -f replit-codemirror-vim-*.tgz
10+
npm pack
11+
12+
# Get the name of the packed file
13+
PACKAGE_FILE=$(ls replit-codemirror-vim-*.tgz | sort -V | tail -n 1)
14+
15+
mv "$PACKAGE_FILE" replit-codemirror-vim-latest.tgz
16+
17+
rm -rf ../.test_package
18+
mkdir -p ../.test_package
19+
cd ../.test_package
20+
21+
cp "$ROOT"/dev/index.ts index.ts
22+
node -e "
23+
const fs = require('fs');
24+
const filePath = 'index.ts';
25+
let data = fs.readFileSync(filePath, 'utf8');
26+
data = data.replace(/\"..\/src\/index\" \/\//g, '');
27+
fs.writeFileSync(filePath, data, 'utf8');
28+
"
29+
30+
echo '{
31+
"name": "test_package",
32+
"scripts": {
33+
"build": "tsc",
34+
"test": "echo \"No tests yet\""
35+
}
36+
}' > package.json
37+
38+
echo '{
39+
"compilerOptions": {
40+
"strict": true,
41+
"noImplicitAny": true,
42+
"strictNullChecks": true,
43+
"strictFunctionTypes": true,
44+
"strictBindCallApply": true,
45+
"strictPropertyInitialization": true,
46+
"noImplicitThis": true,
47+
"alwaysStrict": true,
48+
"noUnusedLocals": true,
49+
"noUnusedParameters": true,
50+
"noImplicitReturns": false,
51+
"noFallthroughCasesInSwitch": true,
52+
"noUncheckedIndexedAccess": true,
53+
"noImplicitOverride": true,
54+
"esModuleInterop": true,
55+
"forceConsistentCasingInFileNames": true,
56+
"module": "commonjs",
57+
"target": "es2020",
58+
"moduleResolution": "node"
59+
},
60+
"include": ["*.ts"],
61+
"exclude": ["node_modules"]
62+
}
63+
' > tsconfig.json
64+
65+
# Install the ace package from the npm pack result
66+
npm i "$ROOT"/replit-codemirror-vim-latest.tgz
67+
npm i codemirror @codemirror/lang-javascript @codemirror/lang-xml
68+
69+
# Install TypeScript
70+
npm i typescript@latest
71+
rm -f index.js
72+
npm run build
73+
74+
# Install old version of TypeScript
75+
npm i typescript@4
76+
rm -f index.js
77+
npm run build

src/cm_adapter.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ export class CodeMirror {
152152
return wordChar.test(ch);
153153
};
154154
static keys: any = keys;
155-
static addClass = function (el, str) { };
156-
static rmClass = function (el, str) { };
155+
static addClass = function (el: any, str: string) { };
156+
static rmClass = function (el: any, str: string) { };
157157
static e_preventDefault = function (e: Event) {
158158
e.preventDefault()
159159
};
@@ -164,6 +164,7 @@ export class CodeMirror {
164164

165165
static lookupKey = function lookupKey(key: string, map: string, handle: Function) {
166166
var result = CodeMirror.keys[key];
167+
if (!result && /^Arrow/.test(key)) result = CodeMirror.keys[key.slice(5)];
167168
if (result) handle(result);
168169
};
169170

@@ -172,7 +173,7 @@ export class CodeMirror {
172173
static signal = signal;
173174

174175
// --------------------------
175-
openDialog(template: Element, callback: Function, options: any) {
176+
openDialog(template: Element, callback: Function|undefined, options: any) {
176177
return openDialog(this, template, callback, options);
177178
};
178179
openNotification(template: Node, options: NotificationOptions) {
@@ -674,7 +675,7 @@ export class CodeMirror {
674675
curOp.cursorActivityHandlers = this._handlers["cursorActivity"] && this._handlers["cursorActivity"].slice();
675676
this.curOp.cursorActivity = true;
676677
};
677-
operation(fn: Function, force?: boolean) {
678+
operation<T>(fn: ()=>T, force?: boolean) {
678679
if (!this.curOp)
679680
this.curOp = { $d: 0 };
680681
this.curOp.$d++;
@@ -727,7 +728,7 @@ export class CodeMirror {
727728

728729
}
729730
};
730-
getOption(name:"firstLineNumber"|"tabSize"): number;
731+
getOption(name:"firstLineNumber"|"tabSize"|"textwidth"): number;
731732
getOption(name:string): number|boolean|string|undefined;
732733
getOption(name: string) {
733734
switch (name) {
@@ -794,7 +795,7 @@ export class CodeMirror {
794795
this.virtualSelection = null;
795796
}
796797

797-
hardWrap(options) {
798+
hardWrap(options: hardWrapOptions) {
798799
return hardWrap(this, options);
799800
}
800801

@@ -875,7 +876,7 @@ function hideDialog(cm: CodeMirror, dialog: Element) {
875876
}
876877
}
877878

878-
function openDialog(me: CodeMirror, template: Element, callback: Function, options: any) {
879+
function openDialog(me: CodeMirror, template: Element, callback: Function|undefined, options: any) {
879880
if (!options) options = {};
880881

881882
closeNotification(me, undefined);
@@ -913,7 +914,7 @@ function openDialog(me: CodeMirror, template: Element, callback: Function, optio
913914

914915
CodeMirror.on(inp, "keydown", function (e: KeyboardEvent) {
915916
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
916-
if (e.keyCode == 13) callback(inp.value);
917+
if (e.keyCode == 13) callback && callback(inp.value);
917918
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
918919
inp.blur();
919920
CodeMirror.e_stop(e);
@@ -968,7 +969,8 @@ function scanForBracket(cm: CodeMirror, where: Pos, dir: -1 | 1, style: any, con
968969
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
969970
}
970971

971-
function findMatchingTag(cm: CodeMirror, pos: Pos): undefined {
972+
function findMatchingTag(cm: CodeMirror, pos: Pos) {
973+
return null;
972974
}
973975

974976
function findEnclosingTag(cm: CodeMirror, pos: Pos) {
@@ -1028,8 +1030,8 @@ class Marker {
10281030
}
10291031

10301032

1031-
1032-
function hardWrap(cm, options) {
1033+
type hardWrapOptions = {from: number, to: number, column?: number, allowMerge?: boolean};
1034+
function hardWrap(cm: CodeMirror, options: hardWrapOptions) {
10331035
var max = options.column || cm.getOption('textwidth') || 80;
10341036
var allowMerge = options.allowMerge != false;
10351037

@@ -1066,7 +1068,7 @@ function hardWrap(cm, options) {
10661068
}
10671069
return row;
10681070

1069-
function findSpace(line, max, min) {
1071+
function findSpace(line: string, max: number, min: number) {
10701072
if (line.length < max)
10711073
return;
10721074
var before = line.slice(0, max);

0 commit comments

Comments
 (0)