qword 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChangeLog +22 -0
- package/README.md +2 -3
- package/assets/style.css +10 -10
- package/client/_clipboard.js +30 -33
- package/client/_clipboard.spec.js +160 -0
- package/client/content.d.ts +8 -0
- package/client/content.js +14 -0
- package/client/content.spec.js +69 -0
- package/client/create.d.ts +32 -0
- package/client/create.js +95 -0
- package/client/create.spec.js +192 -0
- package/client/decorations.d.ts +40 -0
- package/client/decorations.js +110 -0
- package/client/decorations.spec.js +135 -0
- package/client/dom.d.ts +7 -0
- package/client/dom.js +17 -0
- package/client/dom.spec.js +78 -0
- package/client/editor.d.ts +72 -0
- package/client/editor.js +164 -0
- package/client/editor.spec.js +307 -0
- package/client/events.d.ts +7 -0
- package/client/events.js +8 -0
- package/client/events.spec.js +100 -0
- package/client/highlight.d.ts +3 -0
- package/client/highlight.js +82 -0
- package/client/highlight.spec.js +28 -0
- package/client/history.d.ts +4 -0
- package/client/history.js +16 -0
- package/client/history.spec.js +57 -0
- package/client/index.d.ts +60 -0
- package/client/index.js +37 -0
- package/client/loadremote.js +10 -4
- package/client/options.d.ts +30 -0
- package/client/options.js +59 -0
- package/client/options.spec.js +157 -0
- package/client/position.d.ts +21 -0
- package/client/position.js +33 -0
- package/client/position.spec.js +176 -0
- package/client/qword.js +141 -391
- package/client/save.js +2 -2
- package/client/scroll.d.ts +10 -0
- package/client/scroll.js +9 -0
- package/client/scroll.spec.js +58 -0
- package/client/types.d.ts +24 -0
- package/dist/qword.js +175 -1
- package/dist/qword.js.map +1 -1
- package/dist-dev/qword.js +544 -660
- package/package.json +30 -15
- package/server/edit.js +8 -3
- package/server/edit.spec.js +101 -0
- package/test/errors.ts +21 -0
- package/test/types.ts +134 -0
- package/client/codemirror/show-trailing.js +0 -54
- package/client/codemirror/use-soft-tabs.js +0 -38
- package/client/set-key-map.js +0 -3
- package/dist/2b22a33a0a80bb926bbc.png +0 -1
- package/dist/8e9019bd86255ac9a618.png +0 -1
- package/dist/codemirror.js +0 -2
- package/dist/codemirror.js.map +0 -1
- package/dist/dword.js +0 -2
- package/dist/dword.js.map +0 -1
- package/dist-dev/2b22a33a0a80bb926bbc.png +0 -1
- package/dist-dev/8e9019bd86255ac9a618.png +0 -1
- package/dist-dev/codemirror.js +0 -104
- package/dist-dev/dword.js +0 -960
- package/modules/codemirror-emmet/dist/emmet.js +0 -48661
- package/modules/codemirror-emmet/dist/emmet.min.js +0 -8
- package/modules/codemirror-emmet/dist/emmetPlugin.js +0 -840
- package/modules/codemirror-emmet/dist/emmetPlugin.min.js +0 -1
- package/modules/codemirror-emmet/dist/index.html +0 -46
- package/modules/jshint/README.md +0 -114
- package/modules/jshint/dist/jshint-rhino.js +0 -32143
- package/modules/jshint/dist/jshint.js +0 -32141
- package/modules/jshint/package.json +0 -77
package/package.json
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qword",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Web editor based on CodeMirror 6",
|
|
5
5
|
"main": "./server/index.js",
|
|
6
|
-
"exports":
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./server/index.js",
|
|
8
|
+
"./client": "./client/index.js",
|
|
9
|
+
"./client/editor": "./client/editor.js",
|
|
10
|
+
"./client/create": "./client/create.js",
|
|
11
|
+
"./client/content": "./client/content.js",
|
|
12
|
+
"./client/position": "./client/position.js",
|
|
13
|
+
"./client/decorations": "./client/decorations.js",
|
|
14
|
+
"./client/events": "./client/events.js",
|
|
15
|
+
"./client/scroll": "./client/scroll.js",
|
|
16
|
+
"./client/dom": "./client/dom.js",
|
|
17
|
+
"./client/options": "./client/options.js",
|
|
18
|
+
"./client/history": "./client/history.js",
|
|
19
|
+
"./client/highlight": "./client/highlight.js"
|
|
20
|
+
},
|
|
7
21
|
"type": "module",
|
|
8
22
|
"bin": {
|
|
9
23
|
"qword": "bin/qword.js"
|
|
@@ -16,6 +30,7 @@
|
|
|
16
30
|
"start:dev": "madrun start:dev",
|
|
17
31
|
"lint": "madrun lint",
|
|
18
32
|
"test": "madrun test",
|
|
33
|
+
"test:dts": "madrun test:dts",
|
|
19
34
|
"coverage": "madrun coverage",
|
|
20
35
|
"fresh:lint": "madrun fresh:lint",
|
|
21
36
|
"lint:fresh": "madrun lint:fresh",
|
|
@@ -25,10 +40,6 @@
|
|
|
25
40
|
"build:client:dev": "madrun build:client:dev",
|
|
26
41
|
"build:start": "madrun build:start",
|
|
27
42
|
"build:start:dev": "madrun build:start:dev",
|
|
28
|
-
"cp:codemirror:modules": "madrun cp:codemirror:modules",
|
|
29
|
-
"build-progress:codemirror": "madrun build-progress:codemirror",
|
|
30
|
-
"build:codemirror:dev": "madrun build:codemirror:dev",
|
|
31
|
-
"build:codemirror": "madrun build:codemirror",
|
|
32
43
|
"watch:server": "madrun watch:server",
|
|
33
44
|
"watch:client": "madrun watch:client",
|
|
34
45
|
"watch": "madrun watch",
|
|
@@ -49,8 +60,6 @@
|
|
|
49
60
|
"try-to-catch": "^4.0.5"
|
|
50
61
|
},
|
|
51
62
|
"devDependencies": {
|
|
52
|
-
"@babel/core": "^7.0.0",
|
|
53
|
-
"@babel/preset-env": "^7.0.0",
|
|
54
63
|
"@cloudcmd/clipboard": "^2.0.0",
|
|
55
64
|
"@cloudcmd/create-element": "^2.0.2",
|
|
56
65
|
"@codemirror/commands": "^6.10.3",
|
|
@@ -61,14 +70,20 @@
|
|
|
61
70
|
"@codemirror/state": "^6.6.0",
|
|
62
71
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
63
72
|
"@codemirror/view": "^6.42.1",
|
|
73
|
+
"@lezer/highlight": "^1.2.3",
|
|
64
74
|
"@putout/eslint-flat": "^4.0.0",
|
|
75
|
+
"@putout/plugin-convert-webpack-to-rspack": "^1.0.1",
|
|
65
76
|
"@replit/codemirror-vim": "^6.3.0",
|
|
66
|
-
"
|
|
77
|
+
"@rspack/cli": "^2.2.1",
|
|
78
|
+
"@rspack/core": "^2.2.1",
|
|
79
|
+
"@supertape/loader-css": "^1.0.0",
|
|
80
|
+
"@supertape/loader-dom": "^1.0.0",
|
|
81
|
+
"@testing-library/dom": "^10.4.1",
|
|
82
|
+
"@uiw/codemirror-theme-nord": "^4.25.11",
|
|
67
83
|
"callbackify": "^1.1.0",
|
|
68
|
-
"
|
|
69
|
-
"codemirror": "^5.0.0",
|
|
84
|
+
"check-dts": "^1.0.0",
|
|
70
85
|
"css-loader": "^7.1.3",
|
|
71
|
-
"cssnano": "^
|
|
86
|
+
"cssnano": "^9.0.2",
|
|
72
87
|
"daffy": "^1.0.3",
|
|
73
88
|
"emitify": "^4.0.1",
|
|
74
89
|
"es6-promisify": "^7.0.0",
|
|
@@ -84,10 +99,10 @@
|
|
|
84
99
|
"rimraf": "^6.1.2",
|
|
85
100
|
"smalltalk": "^5.0.0",
|
|
86
101
|
"style-loader": "^4.0.0",
|
|
102
|
+
"superc8": "^12.7.0",
|
|
103
|
+
"supertape": "^13.5.2",
|
|
104
|
+
"supertest": "^7.2.2",
|
|
87
105
|
"try-catch": "^4.0.9",
|
|
88
|
-
"url-loader": "^4.0.0",
|
|
89
|
-
"webpack": "^5.1.3",
|
|
90
|
-
"webpack-cli": "^7.0.2",
|
|
91
106
|
"wraptile": "^3.0.0",
|
|
92
107
|
"zipio": "^1.0.2"
|
|
93
108
|
},
|
package/server/edit.js
CHANGED
|
@@ -7,6 +7,8 @@ import Edit from '../json/edit.json' with {
|
|
|
7
7
|
|
|
8
8
|
const HOME = os.homedir();
|
|
9
9
|
|
|
10
|
+
let configPath = `${HOME}/.qword.json`;
|
|
11
|
+
|
|
10
12
|
export default async (req, res, next) => {
|
|
11
13
|
if (req.url !== '/edit.json')
|
|
12
14
|
return next();
|
|
@@ -21,6 +23,10 @@ export default async (req, res, next) => {
|
|
|
21
23
|
res.json(data);
|
|
22
24
|
};
|
|
23
25
|
|
|
26
|
+
export const setConfigPath = (path) => {
|
|
27
|
+
configPath = path;
|
|
28
|
+
};
|
|
29
|
+
|
|
24
30
|
function replace(from, to) {
|
|
25
31
|
for (const name of Object.keys(from)) {
|
|
26
32
|
to[name] = from[name];
|
|
@@ -37,13 +43,12 @@ function copy(from) {
|
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
async function readEdit() {
|
|
40
|
-
const homePath = `${HOME}/.qword.json`;
|
|
41
46
|
const data = copy(Edit);
|
|
42
47
|
|
|
43
|
-
const [error, edit] = await tryToCatch(readjson,
|
|
48
|
+
const [error, edit] = await tryToCatch(readjson, configPath);
|
|
44
49
|
|
|
45
50
|
if (error && error.code !== 'ENOENT')
|
|
46
|
-
throw Error(`qword --config ${
|
|
51
|
+
throw Error(`qword --config ${configPath}: ${error.message}`);
|
|
47
52
|
|
|
48
53
|
if (!edit)
|
|
49
54
|
return data;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {tmpdir} from 'node:os';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {
|
|
4
|
+
mkdtempSync,
|
|
5
|
+
writeFileSync,
|
|
6
|
+
rmSync,
|
|
7
|
+
} from 'node:fs';
|
|
8
|
+
import {test} from 'supertape';
|
|
9
|
+
import request from 'supertest';
|
|
10
|
+
import express from 'express';
|
|
11
|
+
import editFn, {setConfigPath} from './edit.js';
|
|
12
|
+
|
|
13
|
+
const makeApp = () => {
|
|
14
|
+
const app = express();
|
|
15
|
+
app.use(editFn);
|
|
16
|
+
|
|
17
|
+
return app;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const makeTempConfig = (content) => {
|
|
21
|
+
const dir = mkdtempSync(join(tmpdir(), 'qword-'));
|
|
22
|
+
const file = join(dir, 'config.json');
|
|
23
|
+
|
|
24
|
+
writeFileSync(file, content);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
file,
|
|
28
|
+
cleanup: () => rmSync(dir, {
|
|
29
|
+
recursive: true,
|
|
30
|
+
force: true,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
test('edit: returns 200 for /edit.json', async (t) => {
|
|
36
|
+
setConfigPath(join(mkdtempSync(join(tmpdir(), 'qword-')), 'config.json'));
|
|
37
|
+
const response = await request(makeApp()).get('/edit.json');
|
|
38
|
+
|
|
39
|
+
t.equal(response.status, 200);
|
|
40
|
+
t.end();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('edit: returns json content-type for /edit.json', async (t) => {
|
|
44
|
+
setConfigPath(join(mkdtempSync(join(tmpdir(), 'qword-')), 'config.json'));
|
|
45
|
+
|
|
46
|
+
const response = await request(makeApp()).get('/edit.json');
|
|
47
|
+
const result = response.headers['content-type'].includes('json');
|
|
48
|
+
|
|
49
|
+
t.ok(result);
|
|
50
|
+
t.end();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('edit: response body has options field', async (t) => {
|
|
54
|
+
setConfigPath(join(mkdtempSync(join(tmpdir(), 'qword-')), 'config.json'));
|
|
55
|
+
const response = await request(makeApp()).get('/edit.json');
|
|
56
|
+
|
|
57
|
+
t.ok(response.body.options);
|
|
58
|
+
t.end();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('edit: passes through non-edit.json requests', async (t) => {
|
|
62
|
+
setConfigPath(join(mkdtempSync(join(tmpdir(), 'qword-')), 'config.json'));
|
|
63
|
+
|
|
64
|
+
const app = makeApp();
|
|
65
|
+
|
|
66
|
+
app.get('/other', (_req, res) => res.json({
|
|
67
|
+
ok: true,
|
|
68
|
+
}));
|
|
69
|
+
const response = await request(app).get('/other');
|
|
70
|
+
|
|
71
|
+
t.equal(response.status, 200);
|
|
72
|
+
t.end();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('edit: merges options from user config', async (t) => {
|
|
76
|
+
const {file, cleanup} = makeTempConfig(JSON.stringify({
|
|
77
|
+
options: {
|
|
78
|
+
theme: 'dark',
|
|
79
|
+
},
|
|
80
|
+
}));
|
|
81
|
+
setConfigPath(file);
|
|
82
|
+
const response = await request(makeApp()).get('/edit.json');
|
|
83
|
+
|
|
84
|
+
cleanup();
|
|
85
|
+
|
|
86
|
+
t.equal(response.body.options.theme, 'dark');
|
|
87
|
+
t.end();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('edit: returns 404 when config read fails', async (t) => {
|
|
91
|
+
const {file, cleanup} = makeTempConfig('{}');
|
|
92
|
+
const dir = join(file, '..');
|
|
93
|
+
|
|
94
|
+
setConfigPath(dir);
|
|
95
|
+
const response = await request(makeApp()).get('/edit.json');
|
|
96
|
+
|
|
97
|
+
cleanup();
|
|
98
|
+
|
|
99
|
+
t.equal(response.status, 404);
|
|
100
|
+
t.end();
|
|
101
|
+
});
|
package/test/errors.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createEditor,
|
|
3
|
+
setValue,
|
|
4
|
+
positionToOffset,
|
|
5
|
+
setOption,
|
|
6
|
+
} from '../client/index.js';
|
|
7
|
+
|
|
8
|
+
const view = createEditor(document.body);
|
|
9
|
+
|
|
10
|
+
// THROWS Argument of type 'number' is not assignable to parameter of type 'string'
|
|
11
|
+
setValue(view, 5);
|
|
12
|
+
|
|
13
|
+
// THROWS Argument of type 'number' is not assignable to parameter of type 'SourcePosition'
|
|
14
|
+
positionToOffset(view.state.doc, 5);
|
|
15
|
+
|
|
16
|
+
// THROWS Argument of type '"bogus"' is not assignable to parameter of type 'OptionKey'
|
|
17
|
+
setOption(view, 'bogus', 'dark');
|
|
18
|
+
|
|
19
|
+
// THROWS Argument of type '5' is not assignable to parameter of type 'OptionValue'
|
|
20
|
+
setOption(view, 'theme', 5);
|
|
21
|
+
|
package/test/types.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import Editor from '../client/editor.js';
|
|
2
|
+
import {
|
|
3
|
+
createEditor,
|
|
4
|
+
getValue,
|
|
5
|
+
setValue,
|
|
6
|
+
offsetToPosition,
|
|
7
|
+
positionToOffset,
|
|
8
|
+
posFromIndex,
|
|
9
|
+
indexFromPos,
|
|
10
|
+
getCursorIndex,
|
|
11
|
+
getCursor,
|
|
12
|
+
markText,
|
|
13
|
+
addLineClass,
|
|
14
|
+
removeLineClass,
|
|
15
|
+
on,
|
|
16
|
+
off,
|
|
17
|
+
getScrollInfo,
|
|
18
|
+
scrollTo,
|
|
19
|
+
getView,
|
|
20
|
+
refresh,
|
|
21
|
+
observeResize,
|
|
22
|
+
setOption,
|
|
23
|
+
clearHistory,
|
|
24
|
+
} from '../client/index.js';
|
|
25
|
+
|
|
26
|
+
const view = createEditor(document.body, {
|
|
27
|
+
value: 'const a = 3',
|
|
28
|
+
mode: 'javascript',
|
|
29
|
+
keyMap: 'default',
|
|
30
|
+
theme: 'default',
|
|
31
|
+
lineNumbers: true,
|
|
32
|
+
readOnly: false,
|
|
33
|
+
foldGutter: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// content
|
|
37
|
+
const value: string = getValue(view);
|
|
38
|
+
setValue(view, 'const b = 4');
|
|
39
|
+
|
|
40
|
+
// position
|
|
41
|
+
const position = offsetToPosition(view.state.doc, 10);
|
|
42
|
+
const offset: number = positionToOffset(view.state.doc, {
|
|
43
|
+
line: 0,
|
|
44
|
+
ch: 0,
|
|
45
|
+
});
|
|
46
|
+
const pos = posFromIndex(view, 0);
|
|
47
|
+
const idx = indexFromPos(view, {
|
|
48
|
+
line: 0,
|
|
49
|
+
ch: 0,
|
|
50
|
+
});
|
|
51
|
+
const cursor = getCursorIndex(view);
|
|
52
|
+
const {row, column} = getCursor(view);
|
|
53
|
+
|
|
54
|
+
// decorations
|
|
55
|
+
const handle = markText(view, {
|
|
56
|
+
line: 0,
|
|
57
|
+
ch: 0,
|
|
58
|
+
}, {
|
|
59
|
+
line: 0,
|
|
60
|
+
ch: 1,
|
|
61
|
+
}, {
|
|
62
|
+
className: 'hl-keyword',
|
|
63
|
+
});
|
|
64
|
+
handle.clear();
|
|
65
|
+
addLineClass(view, 0, 'text', 'hl-string');
|
|
66
|
+
removeLineClass(view, 0, 'text', 'hl-string');
|
|
67
|
+
|
|
68
|
+
// events
|
|
69
|
+
const binding = on(view, 'keydown', () => {});
|
|
70
|
+
off(view, 'keydown', () => {});
|
|
71
|
+
|
|
72
|
+
// scroll
|
|
73
|
+
const {left, top} = getScrollInfo(view);
|
|
74
|
+
scrollTo(view, left, top);
|
|
75
|
+
|
|
76
|
+
// dom
|
|
77
|
+
const found = getView(document.body);
|
|
78
|
+
refresh(view);
|
|
79
|
+
const unobserve = observeResize(view, document.body);
|
|
80
|
+
unobserve();
|
|
81
|
+
|
|
82
|
+
// options
|
|
83
|
+
setOption(view, 'mode', 'javascript');
|
|
84
|
+
setOption(view, 'theme', 'nord');
|
|
85
|
+
setOption(view, 'keyMap', 'vim');
|
|
86
|
+
|
|
87
|
+
// history
|
|
88
|
+
clearHistory(view, view._historyCompartment, false);
|
|
89
|
+
|
|
90
|
+
// Editor class
|
|
91
|
+
const editor = new Editor(document.body, {
|
|
92
|
+
value: 'const a = 3',
|
|
93
|
+
mode: 'javascript',
|
|
94
|
+
theme: 'default',
|
|
95
|
+
keyMap: 'default',
|
|
96
|
+
});
|
|
97
|
+
editor
|
|
98
|
+
.setValue('const b = 4')
|
|
99
|
+
.focus()
|
|
100
|
+
.moveCursorTo(0, 1)
|
|
101
|
+
.addLineClass(0, 'hl-string')
|
|
102
|
+
.removeLineClass(0, 'hl-string')
|
|
103
|
+
.setMode('javascript')
|
|
104
|
+
.setTheme('nord')
|
|
105
|
+
.setKeyMap('vim')
|
|
106
|
+
.setModeForPath('a.js')
|
|
107
|
+
.clearHistory()
|
|
108
|
+
.on('change', () => {})
|
|
109
|
+
.emit('change', {});
|
|
110
|
+
const editorValue: string = editor.getValue();
|
|
111
|
+
const editorCursor = editor.getCursor();
|
|
112
|
+
const editorPos = editor.posFromIndex(0);
|
|
113
|
+
editor.markRange({
|
|
114
|
+
line: 0,
|
|
115
|
+
ch: 0,
|
|
116
|
+
}, {
|
|
117
|
+
line: 0,
|
|
118
|
+
ch: 1,
|
|
119
|
+
}, 'className').clear();
|
|
120
|
+
|
|
121
|
+
// types compile
|
|
122
|
+
void value;
|
|
123
|
+
void position;
|
|
124
|
+
void offset;
|
|
125
|
+
void pos;
|
|
126
|
+
void idx;
|
|
127
|
+
void cursor;
|
|
128
|
+
void row;
|
|
129
|
+
void column;
|
|
130
|
+
void binding;
|
|
131
|
+
void found;
|
|
132
|
+
void editorValue;
|
|
133
|
+
void editorCursor;
|
|
134
|
+
void editorPos;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* global CodeMirror */
|
|
4
|
-
/* global define */
|
|
5
|
-
|
|
6
|
-
(function(mod) {
|
|
7
|
-
const isFn = (a) => typeof a === 'function';
|
|
8
|
-
|
|
9
|
-
if (typeof exports === 'object' && typeof module === 'object') // CommonJS
|
|
10
|
-
mod(require('../../lib/codemirror'));
|
|
11
|
-
else if (isFn(define) && define.amd) // AMD
|
|
12
|
-
define(['../../lib/codemirror'], mod);
|
|
13
|
-
else // Plain browser env
|
|
14
|
-
mod(CodeMirror);
|
|
15
|
-
})((CodeMirror) => {
|
|
16
|
-
add();
|
|
17
|
-
|
|
18
|
-
CodeMirror.defineOption('showTrailing', false, (cm, val, prev) => {
|
|
19
|
-
if (prev === CodeMirror.Init)
|
|
20
|
-
prev = false;
|
|
21
|
-
|
|
22
|
-
if (prev && !val)
|
|
23
|
-
cm.removeOverlay('trailingspace');
|
|
24
|
-
else if (!prev && val)
|
|
25
|
-
cm.addOverlay({
|
|
26
|
-
token(stream) {
|
|
27
|
-
let ret = null;
|
|
28
|
-
const match = stream.match(/\s+$/);
|
|
29
|
-
|
|
30
|
-
if (match && match[0] !== stream.string)
|
|
31
|
-
ret = 'trailing-whitespace';
|
|
32
|
-
|
|
33
|
-
stream.match(/^\s*\S/);
|
|
34
|
-
|
|
35
|
-
return ret;
|
|
36
|
-
},
|
|
37
|
-
name: 'trailingspace',
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
function add() {
|
|
42
|
-
const style = document.createElement('style');
|
|
43
|
-
|
|
44
|
-
style.setAttribute('data-name', 'js-showTrailing');
|
|
45
|
-
|
|
46
|
-
style.textContent = [
|
|
47
|
-
'.cm-trailing-whitespace {',
|
|
48
|
-
'color: #f80;',
|
|
49
|
-
'text-decoration: underline;',
|
|
50
|
-
'}'].join('');
|
|
51
|
-
|
|
52
|
-
document.head.appendChild(style);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* global CodeMirror */
|
|
4
|
-
/* global define */
|
|
5
|
-
|
|
6
|
-
(function(mod) {
|
|
7
|
-
if (typeof exports === 'object' && typeof module === 'object') // CommonJS
|
|
8
|
-
mod(require('../../lib/codemirror'));
|
|
9
|
-
else if (typeof define === 'function' && define.amd) // AMD
|
|
10
|
-
define(['../../lib/codemirror'], mod);
|
|
11
|
-
else // Plain browser env
|
|
12
|
-
mod(CodeMirror);
|
|
13
|
-
})((CodeMirror) => {
|
|
14
|
-
CodeMirror.defineOption('useSoftTabs', false, (cm) => {
|
|
15
|
-
cm.addKeyMap({
|
|
16
|
-
'Tab'(cm) {
|
|
17
|
-
let line;
|
|
18
|
-
const sel = cm.getSelection('\n');
|
|
19
|
-
const coupleLines = sel.length > 0;
|
|
20
|
-
const isSelected = cm.somethingSelected();
|
|
21
|
-
|
|
22
|
-
if (isSelected) {
|
|
23
|
-
line = cm.getLine(cm.getCursor().line);
|
|
24
|
-
// Indent only if there are multiple lines selected, or if the selection spans a full line
|
|
25
|
-
|
|
26
|
-
if (coupleLines && (sel.includes('\n') || sel.length === line.length)) {
|
|
27
|
-
cm.indentSelection('add');
|
|
28
|
-
}
|
|
29
|
-
} else {
|
|
30
|
-
cm.execCommand('insertSoftTab');
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
'Shift-Tab'(cm) {
|
|
34
|
-
cm.indentSelection('subtract');
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
package/client/set-key-map.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAQAAAC1QeVaAAAAUklEQVR4XqXPYQrAIAhAYW/gXd8NJxTopVqsGEhtf+L9/ERU2k/HSMFQpKcYJeNFI9Be0LCMij8cYyjj5EHIivGBkwLfrbX3IF8PqumVmnDpEG+eDsKibPG2JwAAAABJRU5ErkJggg=="
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAQAAAC1QeVaAAAAnUlEQVR4XoWQQQ6CQAxFewjkJkMCyXgJPMk7AiYczyBeZEAX6AKctGIaN+bt+trk9wtGQc/IkhnoKGxqqiWxOSZalapWFZ6VrIUDExsN0a5JRBq9LoVOR0eEQMoEhKizXhhsn0p1sCWVo7CwOf1RytPL8CPvwuBUoHL6ugeK30CVD1TqK7V/hdpe+VNChhOzV8xWny/+xosHF8578W/Hmc1OOC3wmwAAAABJRU5ErkJggg=="
|