86 lines
3.1 KiB
JavaScript
86 lines
3.1 KiB
JavaScript
// ==UserScript==
|
|
// @name Better CodeHS (Ace Optimized)
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 1.2
|
|
// @description Enable autocomplete, Vim mode, and Gruvbox for CodeHS Ace Editor.
|
|
// @author Qyoh & Gemini
|
|
// @match https://codehs.com/*
|
|
// @grant none
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// --- UTILITIES ---
|
|
function clickButton(selector) {
|
|
const btn = document.querySelector(selector);
|
|
if (btn) btn.click();
|
|
}
|
|
|
|
// --- KEYBINDINGS ---
|
|
document.addEventListener('keydown', (e) => {
|
|
// Ctrl + Enter: Submit
|
|
if (e.ctrlKey && e.key === 'Enter') {
|
|
e.preventDefault();
|
|
clickButton('.StyledButtonKind-sc-1vhfpnt-0.fSozsy.sc-bkbkJK.eraKfR');
|
|
}
|
|
// Alt + C: Check Code
|
|
if (e.altKey && e.key === 'c') {
|
|
e.preventDefault();
|
|
const testTab = document.querySelector('.r.c') || document.querySelector('[data-test="test-cases-tab"]');
|
|
if (testTab) testTab.click();
|
|
setTimeout(() => clickButton('#grading-unit-test-run.btn.btn-main.spinner'), 100);
|
|
}
|
|
});
|
|
|
|
// --- ACE EDITOR INJECTION ---
|
|
function injectAceFeatures() {
|
|
// CodeHS often uses 'ace' globally. If not, we try to find the editor instance.
|
|
const editorEl = document.getElementById("codehs-editor") || document.querySelector('.ace_editor');
|
|
|
|
if (!editorEl || !window.ace) {
|
|
setTimeout(injectAceFeatures, 1000);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Get the existing instance instead of creating a new one to avoid conflicts
|
|
const editor = ace.edit(editorEl);
|
|
|
|
// Set Base Path for external modules (Vim/Themes)
|
|
ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/");
|
|
ace.config.set("modePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/");
|
|
ace.config.set("themePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/");
|
|
|
|
// Enable Autocomplete
|
|
ace.config.loadModule("ace/ext/language_tools", function() {
|
|
editor.setOptions({
|
|
enableBasicAutocompletion: true,
|
|
enableLiveAutocompletion: true,
|
|
enableSnippets: true
|
|
});
|
|
});
|
|
|
|
// Set Theme & Vim
|
|
editor.setTheme("ace/theme/gruvbox");
|
|
editor.setKeyboardHandler("ace/keyboard/vim");
|
|
|
|
console.log("Better CodeHS: Ace Editor configured successfully.");
|
|
} catch (err) {
|
|
console.error("Better CodeHS: Error initializing editor", err);
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
window.addEventListener('load', injectAceFeatures);
|
|
// Re-run if the user navigates between assignments (SPA behavior)
|
|
let lastUrl = location.href;
|
|
new MutationObserver(() => {
|
|
const url = location.href;
|
|
if (url !== lastUrl) {
|
|
lastUrl = url;
|
|
setTimeout(injectAceFeatures, 2000);
|
|
}
|
|
}).observe(document, {subtree: true, childList: true});
|
|
|
|
})(); |