Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests #16

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions dev/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<meta charset=utf8>
<title>CodeMirror view tests</title>

<link rel=stylesheet href="mocha/mocha.css">

<h1>CodeMirror view tests</h1>

<div id="workspace" style="opacity: 0; position: fixed; top: 0; left: 0; width: 20em;"></div>
Expand All @@ -28,7 +26,7 @@ <h1>CodeMirror view tests</h1>
})
}
mocha.setup(options)
await import("../test/webtest-vim")
await import("../test/webtest-emacs")
mocha.run()
</script>

89 changes: 86 additions & 3 deletions dev/web-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<style>
#editor {
height: min(540px, 50vh); width: min(960px, 90vw);
position: absolute; resize: both; overflow: hidden
resize: both; overflow: hidden
}
#editor>.cm-editor {width: 100%; height: 100%}
#editor.split>.cm-editor {height: 50%}
Expand Down Expand Up @@ -469,7 +469,7 @@
if (!/^\w+:/.test(path)) path = host + path;
var onLoad = function(e, val) {
if (e) return processLoadQueue({id: id, path: path});
if (path.slice(-3) == ".ts") {
if (path.slice(-3) == ".ts" || /^import \{/m.test(val)) {
val = ts.transpileModule(val, {
compilerOptions: {
target: "ES2022",
Expand Down Expand Up @@ -520,7 +520,12 @@
}
} else {
var url = require.toUrl(module, ".js");
if (define.fetchedUrls[url] & 1) return false;
if (define.fetchedUrls[url] & 1) {
setTimeout(function() {
processLoadQueue(null, module);
});
return false;
}
define.fetchedUrls[url] |= 1;
loadScript(url, module, processLoadQueue);
}
Expand Down Expand Up @@ -604,6 +609,9 @@
<input type="checkbox" id="wrap"> <label for="wrap">wrap</label>
<input type="checkbox" id="html"> <label for="html">html</label>
<div id="editor"></div>
<br>
<br>
<a href="#test.html" onclick="runTests()">tests</a><br>
<script>
// console.log(ts)
require.config({
Expand Down Expand Up @@ -638,5 +646,80 @@
"dev/index.ts",
], function() {})
</script>
<script>
var it, describe
var old
function runTests() {
if (!old) {
old = {};
Object.keys(define.modules).forEach(k=> old[k] = 1)
} else {
Object.keys(define.modules)
.concat(Object.keys(define.errors))
.forEach(k=> {
if (!old[k])
require.undef(k)
})
}

require.config({
paths: {
"test/webtest-emacs": require.config.baseUrl.replace("dev", "test/webtest-emacs.js"),
}
});
define("test/..", function(require, exports, module) {
module.exports = require("src/index")
});
var suites = Object.create(null)
describe = function(name, fn) {
var suite = {
name,
construct: fn,
tests: Object.create(null),
skipped: Object.create(null),
it: function (name, fn) {
this.tests[name] = fn;
},
skip: function (name, fn) {
this.skipped[name] = fn;
},
};
suites[name] = suite;
it = suite.it = suite.it.bind(suite);
it.skip = suite.skip.bind(suite);
suite.construct();
}

require(["test/webtest-emacs"], async function() {
var total = 0;
var skipped = 0;
var failed = 0;
var passed = 0;
for (var suite of Object.values(suites)) {
var skippedFromSuite = Object.keys(suite.skipped).length;
skipped += skippedFromSuite
total += Object.keys(suite.tests).length
+ skippedFromSuite;
for (var i in suite.tests) {
console.log(i)
try {
await suite.tests[i]()
passed++
} catch(e) {
failed++
console.error(e)
}
}
}
console.log(`
failed: ${failed}
passed: ${passed},
skipped: ${skipped},
from: ${total}
`)
});
}
if (/#test.html/.test(location.hash)) runTests()
</script>
</body>
</html>
60 changes: 36 additions & 24 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BlockCursorPlugin, hideNativeSelection } from "./block-cursor"
import { StateField, StateEffect, ChangeDesc, EditorSelection, Extension, MapMode } from "@codemirror/state"
import { showPanel, EditorView, ViewPlugin, PluginValue, ViewUpdate, keymap } from "@codemirror/view"
import * as commands from "@codemirror/commands"
import { startCompletion } from "@codemirror/autocomplete"
import { startCompletion, completionStatus } from "@codemirror/autocomplete"
import { openSearchPanel } from "@codemirror/search"

const emacsStyle = EditorView.theme({
Expand All @@ -22,7 +22,7 @@ const emacsStyle = EditorView.theme({
})

const emacsPlugin = ViewPlugin.fromClass(class implements PluginValue {
public view: EditorView;
public view: EditorView;
public status = ""
public em: EmacsHandler
blockCursor: BlockCursorPlugin
Expand Down Expand Up @@ -65,19 +65,14 @@ const emacsPlugin = ViewPlugin.fromClass(class implements PluginValue {
}
}, {
eventHandlers: {
keydown: function (e: KeyboardEvent, view: EditorView) {
var result = this.em.handleKeyboard(e)
return !!result;
},
mousedown: function() {
this.em.$emacsMark = null
}
},
provide: plugin => {
return keymap.of([
{
any: function(view, e) {
return !!view.plugin(plugin)?.em.handleKeyboard(e)
}
}
])
}
})


Expand Down Expand Up @@ -176,6 +171,7 @@ class EmacsHandler {
}
static execCommand(command: any, handler: EmacsHandler, args: any, count: number = 1) {
var commandResult = undefined;
if (count < 0) count = -count;
if (typeof command === "function") {
for (var i = 0; i < count; i++) command(handler.view);
} else if (command === "null") {
Expand All @@ -197,6 +193,10 @@ class EmacsHandler {
handleKeyboard(e: KeyboardEvent) {
var keyData = EmacsHandler.getKey(e)
var result = this.findCommand(keyData)

if (/Up|Down/.test(keyData?.[0]) && completionStatus(this.view.state))
return;

if (result && result.command) {
var commandResult = EmacsHandler.execCommand(result.command, this, result.args, result.count)
if (commandResult === false)
Expand Down Expand Up @@ -335,9 +335,9 @@ class EmacsHandler {
pushEmacsMark(p?: EmacsMark, activate?: boolean) {
var prevMark = this.$emacsMark;
if (prevMark)
this.$emacsMarkRing.push(prevMark);
pushUnique(this.$emacsMarkRing, prevMark);
if (!p || activate) this.setEmacsMark(p);
else this.$emacsMarkRing.push(p);
else pushUnique(this.$emacsMarkRing, p);
};

popEmacsMark() {
Expand Down Expand Up @@ -391,6 +391,16 @@ class EmacsHandler {
})
view.dispatch(specs)
}
selectionToEmacsMark() {
var selection = this.view.state.selection;
return selection.ranges.map(x => x.head)
}
}

function pushUnique<T>(array: T[], item:T) {
if (array.length && array[array.length - 1] + "" == item + "")
return;
array.push(item);
}

export const emacsKeys: Record<string, any> = {
Expand Down Expand Up @@ -618,6 +628,7 @@ EmacsHandler.addCommands({
// in multi select mode, ea selection is handled individually

if (args && args.count) {
var newMark = handler.selectionToEmacsMark();
var mark = handler.popEmacsMark();
if (mark) {
var newRanges = mark.map((p: number)=> {
Expand All @@ -626,12 +637,13 @@ EmacsHandler.addCommands({
view.dispatch({
selection: EditorSelection.create(newRanges)
})
handler.$emacsMarkRing.unshift(newMark);
}
return;
}

var mark = handler.emacsMark();
var rangePositions = ranges.map(function (r) { return r.from; });
var rangePositions = ranges.map(function (r) { return r.head; });
var transientMarkModeActive = true;
var hasNoSelection = ranges.every(function (range) { return range.from == range.to; });
// if transientMarkModeActive then mark behavior is a little
Expand All @@ -655,7 +667,7 @@ EmacsHandler.addCommands({
handlesCount: true
},
exchangePointAndMark: {
exec: function exchangePointAndMark$exec(handler: EmacsHandler, args: any) {
exec: function(handler: EmacsHandler, args: any) {
var view = handler.view;
var selection = view.state.selection;
var isEmpty = !selection.ranges.some(r => r.from != r.to)
Expand All @@ -674,6 +686,8 @@ EmacsHandler.addCommands({
if (!lastMark) return;

if (args.count) { // replace mark and point
markRing[markRing.length - 1] = handler.selectionToEmacsMark()

handler.clearSelection();

var newRanges = lastMark.map(x => {
Expand All @@ -682,7 +696,6 @@ EmacsHandler.addCommands({
view.dispatch({
selection: EditorSelection.create(newRanges, selection.mainIndex)
})

} else { // create selection to last mark
var n = Math.min(lastMark.length, selection.ranges.length)
newRanges = []
Expand Down Expand Up @@ -723,22 +736,21 @@ EmacsHandler.addCommands({
handler.pushEmacsMark(null);
// don't delete the selection if it's before the cursor
handler.clearSelection();
commands.selectLineEnd(handler.view);

var view = handler.view;
var state = view.state


var text: string[] = [];
var changes = handler.view.state.selection.ranges.map(function(range) {
var from = range.from;
var to = range.to;
var changes = state.selection.ranges.map(function(range) {
var from = range.head;
var lineObject = state.doc.lineAt(from)

var to = lineObject.to;
var line = state.sliceDoc(from, to)

// remove EOL if only whitespace remains after the cursor
if (/^\s*$/.test(line)) {
if (/^\s*$/.test(line) && to < state.doc.length - 1) {
to += 1;
text.push("\n")
text.push(line + "\n")
} else {
text.push(line)
}
Expand Down
Loading
Loading