Copenhagen is a free, lightweight, and hackable open-source code editor for the web. It’s responsible for running the code editing experiment on Autocode, and it’s written entirely in Vanilla JavaScript with only tokens. You can start playing with it yourself directly by following the installation instructions: Show on GitHub or install (fork) on Autocode.
The documents are available at copenhagen.autocode.com. You can also manipulate your installation right away by creating this repository in AutocodeCopenhagen, which is a simple, lightweight, and extensible code editor that supports popular languages like HTML, CSS, JavaScript, JSON, Markdown, and Plain Text.
free code editor, online code editor, atom code editor, sublime text, best code editor for beginners, open source text editor, code editor download
Features:
- A simple, intuitive API
- Extensible code completion via typeahead
- Configurable hotkeys
- Multi-cursor selection
- Find and replace
- Support for large files (currently up to 100kloc)
- Configurable language settings and highlighting
- Small package size (50kB minified)
- Autogrow mode (default) or maximized view
- Custom autocomplete dropdown support (WIP)
- Mobile support (WIP)
How to make use of it:
1. Load Copenhagen’s JavaScript and CSS information.
<link rel=”stylesheet” href=”./compiled/copenhagen.min.css”> <script src=”./compiled/copenhagen.min.js”></script>
2. Create a container for the editor and decide which language you wish to use: “javascript”, “JSON”, “markdown”, “HTML”, “css” and “text”.
<div class="editor" data-language="javascript" data-maxrows="20"> // JS Code Here </div>
3. Initialize the Copenhagen editor and finished.
window.addEventListener('DOMContentLoaded', function () { var editor = Copenhagen.initSelectorAll('.editor'); });
4. All configurations that may be passed by way of both JavaScript or data-option
attributes:
var editor = new Copenhagen.Editor({ // enable readonly here readonly: false, // hide the editor hidden: false, // disable the editor booleandisabled: false, // determine whether to take up the entirety of the relative parent maximized: false, // minimum number of rows of the editor rows: 1, // maximum number of rows of the editor rmaxrows: 30, // determine whether you can "tab out" of the editor tabout: false, // disable line numbers here nolines: false, });
5. Add your personal autocomplete to the editor.
function CodeCompleter () { this.suggestions = this.generateSuggestions(this.suggestionMap); }; CodeCompleter.prototype.cursorCharacter = '·'; CodeCompleter.prototype.wildcardWordCharacter = '¤'; CodeCompleter.prototype.wildcardPhraseCharacter = '…'; CodeCompleter.prototype.wildcardReplaceCharacter = '\\$1'; CodeCompleter.prototype.suggestionMap = { 'javascript': [ 'const ', 'const ¤ = ', 'const {…} = ', 'const […] = ', 'console.log(`·Got here: A·`);', 'console.error(`·Error·`);', 'let ', 'let ¤ = ', 'let {…} = ', 'let […] = ', 'var ', 'var ¤ = ', 'var {…} = ', 'var […] = ', 'lib.', 'module.exports = ', 'module.exports = async ', 'return ', 'require(\'·\')', 'class ', 'class ¤ {·}', 'function ', 'function (·)', 'function ¤ (·)', 'function () {·}', 'function ¤ () {·}', 'function (…) {·}', 'function ¤ (…) {·}', 'if (·true·)', 'if () {·}', 'if (…) {·}', 'else ', 'else {·}', 'else if (·true·)', 'for (let i = 0; i < ·10·; i++)', 'for () {·}', 'for (…) {·}', 'while (·true·)', 'while () {·}', 'while (…) {·}', 'await ', 'await lib.', 'await new Promise((resolve, reject) => {·});', 'async ', 'async (·)', '() => {·}', '(…) => {·}', '/**\n * ·\n */', '* @param {·}', '* @param {…} ·paramName·', '* @returns {·}', '* @returns {…} ·returnValue·', 'true', 'false', 'null', 'new ', 'new Promise((resolve, reject) => {·});', 'Promise((resolve, reject) => {·});', 'Promise.all([·]);', 'setTimeout(() => {·}, 1);', 'setInterval(() => {·}, 1);', 'try {·}', 'catch (e) {·}', 'catch (…) {·}', 'throw ', 'throw new Error(`·Oops!·`);', 'new Error(`·Oops!·`)', 'Error(`·Oops!·`)', 'Error(…)' ] }; CodeCompleter.prototype.generateSuggestions = function () { var suggestionMap = this.suggestionMap; var cursorCharacter = this.cursorCharacter; return Object.keys(suggestionMap).reduce(function (suggestions, language) { var phraseList = suggestionMap[language].map(function (value) { var cursorStart = value.indexOf(cursorCharacter); var cursorEnd = value.lastIndexOf(cursorCharacter); var cursorLength = 0; if (cursorStart !== cursorEnd) { cursorLength = cursorEnd - cursorStart - 1; value = value.slice(0, cursorEnd) + value.slice(cursorEnd + 1); } var adjust = cursorStart === -1 ? 0 : cursorStart - value.length + 1; if (adjust) { value = value.substr(0, value.length + adjust - 1) + value.substr(value.length + adjust); } return { value: value, adjust: adjust, cursorLength: cursorLength }; }.bind(this)); suggestions[language] = { lookup: this.generateLookupTrie(phraseList), }; return suggestions; }.bind(this), {}); }; CodeCompleter.prototype.generateLookupTrie = function (phraseList) { var wildcardWord = this.wildcardWordCharacter; var wildcardPhrase = this.wildcardPhraseCharacter; var root = {}; var curNode, node, phrase, value; var i, j, k; for (i = 0; i < phraseList.length; i++) { phrase = phraseList[i]; value = phrase.value; for (j = value.length - 1; j >= 0; j--) { curNode = root; for (k = j; k >= 0; k--) { char = value[k]; curNode[char] = curNode[char] || {}; if (char === wildcardWord || char === wildcardPhrase) { curNode[char][char] = curNode[char][char] || curNode[char]; } curNode = curNode[char]; } curNode.phrases = curNode.phrases || []; curNode.phrases.push({ value: value, ranking: i, adjust: phrase.adjust, cursorLength: phrase.cursorLength, re: phrase.re }); } } return root; }; CodeCompleter.prototype.complete = function (tree, value, index, subs, inWildcard) { index = index || 0; subs = subs || []; inWildcard = inWildcard || ''; var wildcardWord = this.wildcardWordCharacter; var wildcardPhrase = this.wildcardPhraseCharacter; var wildcardReplace = this.wildcardReplaceCharacter; var char; var results = []; var node = tree; for (var i = value.length - 1; i >= 0; i--) { index++; var char = value[i]; if (node[wildcardWord]) { if (char.match(/[0-9a-z_$]/i)) { var newSubs = subs.slice(); if (inWildcard) { newSubs[0] = char + newSubs[0]; } else { newSubs.unshift(char); } results = results.concat( this.complete(node[wildcardWord], value.substr(0, i), index - 1, newSubs, wildcardWord) ); } } if (node[wildcardPhrase]) { if (char.match(/[^\(\)\[\]\{\}\"\'\`]/i)) { var newSubs = subs.slice(); if (inWildcard) { newSubs[0] = char + newSubs[0]; } else { newSubs.unshift(char); } results = results.concat( this.complete(node[wildcardPhrase], value.substr(0, i), index - 1, newSubs, wildcardPhrase) ); } } if (node[char]) { inWildcard = ''; if (node.phrases && (char === ' ')) { results = results.concat( node.phrases.map(function (p) { var curSubs = subs.slice(); return { value: p.value.replace( new RegExp('(' + [wildcardWord, wildcardPhrase, wildcardReplace].join('|') + ')', 'gi'), function ($0) { return curSubs.shift() || ''; } ), ranking: p.ranking, adjust: p.adjust, offset: index - 1 + subs.join('').length, cursorLength: p.cursorLength }; }) ); } node = node[char]; } else { break; } } if (node.phrases && (i < 0 || value[i] === ' ')) { (i < 0) && index++; results = results.concat( node.phrases.map(function (p) { var curSubs = subs.slice(); return { value: p.value.replace( new RegExp('(' + [wildcardWord, wildcardPhrase, wildcardReplace].join('|') + ')', 'gi'), function ($0) { return curSubs.shift() || ''; } ), ranking: p.ranking, adjust: p.adjust, offset: index - 1 + subs.join('').length, cursorLength: p.cursorLength }; }) ); } return results .sort(function (p1, p2) { return p2.offset - p1.offset || p1.ranking - p2.ranking; }) .filter(function (p) { return p.offset < p.value.length; }); }; CodeCompleter.protot
6. API strategies.
// Create a custom autocompletion detector to add your own autocomplete box editor.addAutocomplete(name, function(editor, selection, inString, inComment){ // ... }) // Add custom hotkeys editor.addHotkey(keys, function(value, cursors){ // ... }) // Disable animation editor.animateNo() // Blur the editor editor.blur() // Enable autocomplete editor.canSuggest() // Clear history editor.clearHistory() // Clear meta data editor.clearMetadata(metadata) // Disable editor.disable() // Emulate a user action editor.emulateUserAction(userAction) // Enable editor.enable() // Show find and replace dialog editor.find(value) // Find the complement of a character at a specific index based on the language dictionary editor.findComplements(value, index) // Set focus to the editor editor.focus() // Retrieve the active formatter function based on the active language editor.getActiveFormatter() // Retrieve the currently active language for the editor editor.getActiveLanguage() // Retrieve the currently active language dictionary for the editor editor.getActiveLanguageDictionary() // Retrieves the formatter function for a language or return the text formatter if it is not found editor.getFormatter(language) // Retrieve metadata from the editor editor.getMetadata(metadata, defaultValue) // Retrieve the current value of the editor editor.getValue() // Navigate the user action history editor.gotoHistory(amount) // Determine whether the editor is focused editor.hasFocus() // Hide the editor editor.hide() // Determine whether a specific character index is within a comment or not based on the language dictionary editor.inComment(index) // Determine whether a specific character index is within a string or not based on the language dictionary. editor.inString(index) // Retrieve the current read-only status of the editor. editor.isReadOnly() // Open the editor instance editor.open(element, focus, replaceText) // Remove an autocompletion detector editor.removeAutocomplete() // Remove a hotkey handler editor.removeHotkey(hotkey) // Render the editor on the next available frame editor.render(value, forceRender) // Dispatches a "save" event and creates a history entry if the user has performed an action editor.save(value) // Scrolls the editor by a visible "page" amount based on the height of the editor // "up" or "down" editor.scrollPage(direction) // Scrolls to the currently selected text in the editor editor.scrollToText() // Scrolls to a specific line index in the editor editor.scrollToLine(index) // Scrolls the editor to a specific (x, y) coordinate from the top left of the editor editor.scrollTo(x, y) // Select text in the editor at a specific start and end index editor.select(start, end) // Set emulation mode. editor.setEmulationMode(true/false) // Set an error state in the editor editor.setError(lineIndex, column) // Set a custom formatter for a language editor.setFormatter(language, function(){ // ... }) // Set the language editor.setLanguage(language) // Set maximized mode on the editor so that it takes up all of its relative parent's height editor.setMaximized(true/false) // Sets metadata on the editor editor.setMetadata(metadata, value) // Set read-only mode on the editor editor.setReadOnly(true/false) // Set the value of the editor editor.setValue(value) // Show the editor editor.show() // Perform a user action editor.userAction(userAction)
Simple Extensible Code Editor, Copenhagen Editor Plugin/Github
See Demo And Download
Official Website(acode): Click Here
This superior jQuery/javascript plugin is developed by acode. For extra advanced usage, please go to the official website.