Compare commits
No commits in common. "7fd6f8333e14fd2b8a19819068a79dea384c6604" and "792af9617036030013aedaea7d07be97f09273d3" have entirely different histories.
7fd6f8333e
...
792af96170
7 changed files with 1306 additions and 6225 deletions
13
codemirror-element/Makefile
Normal file
13
codemirror-element/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
NODE_BIN=node_modules/.bin
|
||||||
|
|
||||||
|
DEST=../thinks/static/thinks
|
||||||
|
|
||||||
|
$(DEST)/code-editor.mjs: code-editor.bundle.mjs
|
||||||
|
cp $< $@
|
||||||
|
|
||||||
|
code-editor.terser.mjs: code-editor.bundle.mjs
|
||||||
|
$(NODE_BIN)/terser --compress --mangle -- $< > $@
|
||||||
|
|
||||||
|
code-editor.bundle.mjs: code-editor.mjs
|
||||||
|
$(NODE_BIN)/rollup $< -f es -p @rollup/plugin-node-resolve -o $@
|
||||||
|
|
73
codemirror-element/code-editor.mjs
Normal file
73
codemirror-element/code-editor.mjs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import {basicSetup} from "codemirror";
|
||||||
|
import {EditorView, keymap} from "@codemirror/view";
|
||||||
|
import {EditorState} from "@codemirror/state";
|
||||||
|
import {python} from "@codemirror/lang-python";
|
||||||
|
import {r} from "codemirror-lang-r";
|
||||||
|
import {vim} from "@replit/codemirror-vim";
|
||||||
|
import {indentWithTab} from "@codemirror/commands";
|
||||||
|
|
||||||
|
window.EditorView = EditorView;
|
||||||
|
|
||||||
|
const languages = {
|
||||||
|
'python': python,
|
||||||
|
'r': r
|
||||||
|
}
|
||||||
|
|
||||||
|
export function codemirror_editor(language, options) {
|
||||||
|
const language_plugin = languages[language];
|
||||||
|
|
||||||
|
options = Object.assign({
|
||||||
|
extensions: [
|
||||||
|
vim(),
|
||||||
|
basicSetup,
|
||||||
|
keymap.of([indentWithTab]),
|
||||||
|
EditorView.updateListener.of(update => {
|
||||||
|
if(!options?.onChange || update.changes.desc.empty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
options.onChange(update);
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
let editor = new EditorView(options);
|
||||||
|
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class CodeEditorElement extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.language = this.getAttribute('language') || '';
|
||||||
|
const shadowRoot = this.attachShadow({mode: 'open'});
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.init_editor();
|
||||||
|
}
|
||||||
|
|
||||||
|
init_editor() {
|
||||||
|
const code = this.textContent;
|
||||||
|
const code_tag = this.shadowRoot;
|
||||||
|
|
||||||
|
this.codeMirror = codemirror_editor(
|
||||||
|
this.language,
|
||||||
|
{
|
||||||
|
doc: code,
|
||||||
|
parent: code_tag,
|
||||||
|
root: this.shadowRoot,
|
||||||
|
onChange: update => this.onChange(update)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange() {
|
||||||
|
const code = this.codeMirror.state.doc.toString();
|
||||||
|
this.value = code;
|
||||||
|
this.dispatchEvent(new CustomEvent('change'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("code-editor", CodeEditorElement);
|
20
codemirror-element/package.json
Normal file
20
codemirror-element/package.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "codemirror-element",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/lang-python": "^6.1.2",
|
||||||
|
"@replit/codemirror-vim": "^6.2.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
|
"codemirror-lang-r": "^0.1.0-2",
|
||||||
|
"rollup": "^3.20.6",
|
||||||
|
"terser": "^5.17.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,23 +34,6 @@ class JJController:
|
||||||
git_url = settings.GIT_REPO_URL_TEMPLATE.format(name=self.think.slug)
|
git_url = settings.GIT_REPO_URL_TEMPLATE.format(name=self.think.slug)
|
||||||
self.run(['jj','git','remote','add','origin', git_url])
|
self.run(['jj','git','remote','add','origin', git_url])
|
||||||
|
|
||||||
@ensure_jj
|
|
||||||
def ignore_paths(self, paths):
|
|
||||||
paths = self.clean_paths(paths)
|
|
||||||
gitignore = self.root / '.gitignore'
|
|
||||||
if len(paths) == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
if gitignore.exists():
|
|
||||||
with open(gitignore) as f:
|
|
||||||
ignored = f.read().strip().split('\n')
|
|
||||||
ignored += [p for p in paths if p not in ignored]
|
|
||||||
else:
|
|
||||||
ignored = paths
|
|
||||||
|
|
||||||
with open(gitignore, 'w') as f:
|
|
||||||
f.write('\n'.join(ignored))
|
|
||||||
|
|
||||||
@ensure_jj
|
@ensure_jj
|
||||||
def status(self):
|
def status(self):
|
||||||
res = self.run(['jj','st'])
|
res = self.run(['jj','st'])
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,6 @@
|
||||||
--editor-size: 50%;
|
--editor-size: 50%;
|
||||||
|
|
||||||
--background: hsl(70,100%,95%);
|
--background: hsl(70,100%,95%);
|
||||||
--default-background: white;
|
|
||||||
--color: black;
|
--color: black;
|
||||||
--button-bg: #ddd;
|
--button-bg: #ddd;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +16,6 @@
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
--background: hsl(70,100%,8%);
|
--background: hsl(70,100%,8%);
|
||||||
--default-background: black;
|
|
||||||
--color: white;
|
--color: white;
|
||||||
--button-bg: #333;
|
--button-bg: #333;
|
||||||
}
|
}
|
||||||
|
@ -239,9 +237,10 @@ input {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
& code-editor {
|
& #code-editor {
|
||||||
background: var(--default-background);
|
|
||||||
display: block;
|
display: block;
|
||||||
|
max-width: 50vw;
|
||||||
|
padding-bottom: 10em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6471,9 +6471,6 @@ var $author$project$App$ReloadPreview = {$: 'ReloadPreview'};
|
||||||
var $author$project$App$RunCommand = function (a) {
|
var $author$project$App$RunCommand = function (a) {
|
||||||
return {$: 'RunCommand', a: a};
|
return {$: 'RunCommand', a: a};
|
||||||
};
|
};
|
||||||
var $author$project$App$RunningCommand = function (a) {
|
|
||||||
return {$: 'RunningCommand', a: a};
|
|
||||||
};
|
|
||||||
var $author$project$App$SaveContent = function (a) {
|
var $author$project$App$SaveContent = function (a) {
|
||||||
return {$: 'SaveContent', a: a};
|
return {$: 'SaveContent', a: a};
|
||||||
};
|
};
|
||||||
|
@ -6829,11 +6826,7 @@ var $author$project$App$update = F2(
|
||||||
case 'RunCommand':
|
case 'RunCommand':
|
||||||
var cmd = msg.a;
|
var cmd = msg.a;
|
||||||
return _Utils_Tuple2(
|
return _Utils_Tuple2(
|
||||||
_Utils_update(
|
|
||||||
model,
|
model,
|
||||||
{
|
|
||||||
log: $author$project$App$RunningCommand(cmd)
|
|
||||||
}),
|
|
||||||
$elm$http$Http$post(
|
$elm$http$Http$post(
|
||||||
{
|
{
|
||||||
body: $elm$http$Http$multipartBody(
|
body: $elm$http$Http$multipartBody(
|
||||||
|
@ -7192,27 +7185,6 @@ var $elm$html$Html$Attributes$action = function (uri) {
|
||||||
};
|
};
|
||||||
var $elm$file$File$decoder = _File_decoder;
|
var $elm$file$File$decoder = _File_decoder;
|
||||||
var $elm$html$Html$details = _VirtualDom_node('details');
|
var $elm$html$Html$details = _VirtualDom_node('details');
|
||||||
var $elm$core$List$drop = F2(
|
|
||||||
function (n, list) {
|
|
||||||
drop:
|
|
||||||
while (true) {
|
|
||||||
if (n <= 0) {
|
|
||||||
return list;
|
|
||||||
} else {
|
|
||||||
if (!list.b) {
|
|
||||||
return list;
|
|
||||||
} else {
|
|
||||||
var x = list.a;
|
|
||||||
var xs = list.b;
|
|
||||||
var $temp$n = n - 1,
|
|
||||||
$temp$list = xs;
|
|
||||||
n = $temp$n;
|
|
||||||
list = $temp$list;
|
|
||||||
continue drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var $elm$html$Html$input = _VirtualDom_node('input');
|
var $elm$html$Html$input = _VirtualDom_node('input');
|
||||||
var $elm$html$Html$Attributes$name = $elm$html$Html$Attributes$stringProperty('name');
|
var $elm$html$Html$Attributes$name = $elm$html$Html$Attributes$stringProperty('name');
|
||||||
var $author$project$App$form = F3(
|
var $author$project$App$form = F3(
|
||||||
|
@ -7235,18 +7207,6 @@ var $author$project$App$form = F3(
|
||||||
_List_Nil)
|
_List_Nil)
|
||||||
])));
|
])));
|
||||||
});
|
});
|
||||||
var $elm$core$Dict$fromList = function (assocs) {
|
|
||||||
return A3(
|
|
||||||
$elm$core$List$foldl,
|
|
||||||
F2(
|
|
||||||
function (_v0, dict) {
|
|
||||||
var key = _v0.a;
|
|
||||||
var value = _v0.b;
|
|
||||||
return A3($elm$core$Dict$insert, key, value, dict);
|
|
||||||
}),
|
|
||||||
$elm$core$Dict$empty,
|
|
||||||
assocs);
|
|
||||||
};
|
|
||||||
var $elm$html$Html$nav = _VirtualDom_node('nav');
|
var $elm$html$Html$nav = _VirtualDom_node('nav');
|
||||||
var $elm$virtual_dom$VirtualDom$MayPreventDefault = function (a) {
|
var $elm$virtual_dom$VirtualDom$MayPreventDefault = function (a) {
|
||||||
return {$: 'MayPreventDefault', a: a};
|
return {$: 'MayPreventDefault', a: a};
|
||||||
|
@ -7261,38 +7221,7 @@ var $elm$html$Html$Events$preventDefaultOn = F2(
|
||||||
var $elm$html$Html$section = _VirtualDom_node('section');
|
var $elm$html$Html$section = _VirtualDom_node('section');
|
||||||
var $elm$html$Html$span = _VirtualDom_node('span');
|
var $elm$html$Html$span = _VirtualDom_node('span');
|
||||||
var $elm$html$Html$summary = _VirtualDom_node('summary');
|
var $elm$html$Html$summary = _VirtualDom_node('summary');
|
||||||
var $elm$core$Maybe$withDefault = F2(
|
|
||||||
function (_default, maybe) {
|
|
||||||
if (maybe.$ === 'Just') {
|
|
||||||
var value = maybe.a;
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
return _default;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var $author$project$App$editor_pane = function (model) {
|
var $author$project$App$editor_pane = function (model) {
|
||||||
var languages = $elm$core$Dict$fromList(
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
_Utils_Tuple2('js', 'javascript'),
|
|
||||||
_Utils_Tuple2('mjs', 'javascript'),
|
|
||||||
_Utils_Tuple2('py', 'python'),
|
|
||||||
_Utils_Tuple2('r', 'r'),
|
|
||||||
_Utils_Tuple2('R', 'r'),
|
|
||||||
_Utils_Tuple2('elm', 'elm')
|
|
||||||
]));
|
|
||||||
var extension = A2(
|
|
||||||
$elm$core$Maybe$withDefault,
|
|
||||||
'',
|
|
||||||
$elm$core$List$head(
|
|
||||||
A2(
|
|
||||||
$elm$core$List$drop,
|
|
||||||
1,
|
|
||||||
A2($elm$core$String$split, '.', model.file_path))));
|
|
||||||
var language = A2(
|
|
||||||
$elm$core$Maybe$withDefault,
|
|
||||||
'',
|
|
||||||
A2($elm$core$Dict$get, extension, languages));
|
|
||||||
return A2(
|
return A2(
|
||||||
$elm$html$Html$section,
|
$elm$html$Html$section,
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
|
@ -7466,8 +7395,7 @@ var $author$project$App$editor_pane = function (model) {
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
['target', 'value']),
|
['target', 'value']),
|
||||||
$elm$json$Json$Decode$string))),
|
$elm$json$Json$Decode$string))),
|
||||||
A2($elm$html$Html$Attributes$attribute, 'content', model.file_content),
|
A2($elm$html$Html$Attributes$attribute, 'content', model.file_content)
|
||||||
A2($elm$html$Html$Attributes$attribute, 'language', language)
|
|
||||||
]),
|
]),
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
[
|
||||||
|
@ -7650,7 +7578,6 @@ var $author$project$App$header = function (model) {
|
||||||
var $author$project$App$ToggleLog = function (a) {
|
var $author$project$App$ToggleLog = function (a) {
|
||||||
return {$: 'ToggleLog', a: a};
|
return {$: 'ToggleLog', a: a};
|
||||||
};
|
};
|
||||||
var $elm$html$Html$code = _VirtualDom_node('code');
|
|
||||||
var $elm$html$Html$dd = _VirtualDom_node('dd');
|
var $elm$html$Html$dd = _VirtualDom_node('dd');
|
||||||
var $elm$html$Html$div = _VirtualDom_node('div');
|
var $elm$html$Html$div = _VirtualDom_node('div');
|
||||||
var $elm$html$Html$dl = _VirtualDom_node('dl');
|
var $elm$html$Html$dl = _VirtualDom_node('dl');
|
||||||
|
@ -7741,28 +7668,6 @@ var $author$project$App$log_pane = function (model) {
|
||||||
]))
|
]))
|
||||||
]))
|
]))
|
||||||
]));
|
]));
|
||||||
case 'RunningCommand':
|
|
||||||
var cmd = _v0.a;
|
|
||||||
return A2(
|
|
||||||
$elm$html$Html$div,
|
|
||||||
_List_Nil,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$p,
|
|
||||||
_List_Nil,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$text('Running command '),
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$code,
|
|
||||||
_List_Nil,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$text(cmd)
|
|
||||||
]))
|
|
||||||
]))
|
|
||||||
]));
|
|
||||||
case 'CommandResult':
|
case 'CommandResult':
|
||||||
var stdout = _v0.a;
|
var stdout = _v0.a;
|
||||||
var stderr = _v0.b;
|
var stderr = _v0.b;
|
||||||
|
@ -7887,6 +7792,27 @@ var $author$project$App$SetCommand = function (a) {
|
||||||
};
|
};
|
||||||
var $author$project$App$ShowCommitModal = {$: 'ShowCommitModal'};
|
var $author$project$App$ShowCommitModal = {$: 'ShowCommitModal'};
|
||||||
var $author$project$App$Upload = {$: 'Upload'};
|
var $author$project$App$Upload = {$: 'Upload'};
|
||||||
|
var $elm$core$List$drop = F2(
|
||||||
|
function (n, list) {
|
||||||
|
drop:
|
||||||
|
while (true) {
|
||||||
|
if (n <= 0) {
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
if (!list.b) {
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
var x = list.a;
|
||||||
|
var xs = list.b;
|
||||||
|
var $temp$n = n - 1,
|
||||||
|
$temp$list = xs;
|
||||||
|
n = $temp$n;
|
||||||
|
list = $temp$list;
|
||||||
|
continue drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
var $elm$html$Html$li = _VirtualDom_node('li');
|
var $elm$html$Html$li = _VirtualDom_node('li');
|
||||||
var $elm$core$Basics$not = _Basics_not;
|
var $elm$core$Basics$not = _Basics_not;
|
||||||
var $elm$html$Html$Events$onClick = function (msg) {
|
var $elm$html$Html$Events$onClick = function (msg) {
|
||||||
|
|
Loading…
Reference in a new issue