Monaco Editor offers VIM key bindings. I also want to make the line numbers relative when using the VIM mode. Is there any API in the monaco global object which I can use to achieve this?
Note: I don't own the code base. I want to use this in a website that already has a monaco editor instance.
I went through the global object and could not find anything useful.
[
"create",
"onDidCreateEditor",
"createDiffEditor",
"createDiffNavigator",
"createModel",
"setModelLanguage",
"setModelMarkers",
"getModelMarkers",
"onDidChangeMarkers",
"getModels",
"getModel",
"onDidCreateModel",
"onWillDisposeModel",
"onDidChangeModelLanguage",
"createWebWorker",
"colorizeElement",
"colorize",
"colorizeModelLine",
"tokenize",
"defineTheme",
"setTheme",
"remeasureFonts",
"registerCommand",
"AccessibilitySupport",
"ContentWidgetPositionPreference",
"CursorChangeReason",
"DefaultEndOfLine",
"EditorAutoIndentStrategy",
"EditorOption",
"EndOfLinePreference",
"EndOfLineSequence",
"MinimapPosition",
"MouseTargetType",
"OverlayWidgetPositionPreference",
"OverviewRulerLane",
"RenderLineNumbersType",
"RenderMinimap",
"ScrollbarVisibility",
"ScrollType",
"TextEditorCursorBlinkingStyle",
"TextEditorCursorStyle",
"TrackedRangeStickiness",
"WrappingIndent",
"InjectedTextCursorStops",
"PositionAffinity",
"ConfigurationChangedEvent",
"BareFontInfo",
"FontInfo",
"TextModelResolvedOptions",
"FindMatch",
"ApplyUpdateResult",
"EditorType",
"EditorOptions"
]
Simply set lineNumbers to "relative".
monaco.editor.create(document.getElementById('container'), {
value: `function x() {
console.log("Hello world!");
}`,
language: 'javascript',
theme: 'vs-dark',
lineNumbers: 'relative'
});
<link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.min.css">
<div id="container" style="height:400px;border:1px solid black;"></div>
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs' } }</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.js"></script>
Given that you want to dynamically change the options and you probably don't have access to the editor instance, you can find the active editors on the page using the global monaco object with monaco.editor.getEditors(), which returns an array of all active instances, then use updateOptions() to customize the line numbers.
In your case it'd look something like:
// anywhere in the JS code
monaco.editor.getEditors()[0].updateOptions({
lineNumbers: 'relative'
});
Related
I am creating a website in which I am trying to embed code blocks. Someone referred me to the CodeMirror library and thereafter I am trying to have some Javascript code in a code block .
I have incorporated the CodeMirror CSS and JS libraries into my HTMl
file and have created an instance of CodeMirror.
I managed to create a code block. But the code block doesn't apply any formatting/styling to the text in regards to whether it is Javascript or not
It just shows a code block with plain text. I have till now implemented the following code.
At the beginning I defined the following lines:
<link rel="stylesheet" href="codemirror-5.47.0/lib/codemirror.css">
<script src="codemirror-5.47.0/lib/codemirror.js"></script>
<script type="text/javascript" language="javascript">
window.load = function () {
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeeditor"), {
mode: "javascript",
lineNumbers: true
});
myCodeMirror.setSize(500, 300);
}
</script>
<textarea id="codeeditor" rows="20" cols="100">
var GetArray = function (Feature) {var dic = { "Bedrijfsvestigingen": ["bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_ALandbouw_BosbouwEnVisserij", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_B-fNijverheidEnEnergie", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_G_p_IHandelEnHoreca", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_H_p_JVervoer_InformatieEnCommunicatie", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_K-lFinancieleDiensten_OnroerendGoed", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_M-nZakelijkeDienstverlening", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_R-uCultuur_Recreatie_OverigeDiensten", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenTotaal"]};
</textarea>
The result is thus a code block with plain text and thus not formatting have been applied on JavaScript code. In case someone knows a solution to this problem, it would be nice to have a pure Javascript solution, since for example I am not familiar with jQuery for example.
You seem to have forgotten to import the "mode"-file; and probably some addons.
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeeditor"), {
mode: "javascript",
lineNumbers: true
});
//myCodeMirror.setSize(500, 300);
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/codemirror.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/mode/javascript/javascript.min.js"></script>
<textarea id="codeeditor" rows="20" cols="100">
var GetArray = function(Feature) {
var dic = {
"Bedrijfsvestigingen": [
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_ALandbouw_BosbouwEnVisserij",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_B-fNijverheidEnEnergie",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_G_p_IHandelEnHoreca",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_H_p_JVervoer_InformatieEnCommunicatie",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_K-lFinancieleDiensten_OnroerendGoed",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_M-nZakelijkeDienstverlening",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_R-uCultuur_Recreatie_OverigeDiensten",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenTotaal"
]
};
}
</textarea>
I would like, to the graph below,
<link href="https://cdnjs.cloudflare.com/ajax/libs/mermaid/7.0.0/mermaid.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/7.0.0/mermaid.js"></script>
<div class="mermaid">
graph TD;
A[hello]
B[an <b>important</b> link]
A-->B
</div>
to add an actual link under link pointing to http://google.com.
I tried to modify the relevant node to
B[an <b>important</b> link]
but this breaks (crashes) the graph. Specifically, I noticed that what is not accepted is the href element.
Is it possible to add a link in the mermaid node description?
EDIT: I opened a bug report on the mermaid.js repository. Not fixed yet as of June 2017.
I know it's late but: I was searching for a similar thing and found this. Your problem are the " of the href definition breaking the mermaid syntax.
I could achieve what you wanted to do by using
B[an <b>important</b> <a href='http://google.com'>link</a>]
so replacing the doublequotes " of the href definition with single ones '
See the example here.
Update a year later
in a newer version of mermaid this is not directly supported anymore (ಠ_ಠ)
more about it under the version 8.2.0 CHANGELOG
Now you'll need to additionally allow unsecure content via
mermaidAPI.initialize({
securityLevel: 'loose'
});
Sure, its possible to add a link in Mermaid node, as shown below:
mermaid.initialize({
startOnLoad: true
});
<script src="https://cdn.rawgit.com/knsv/mermaid/6.0.0/dist/mermaid.min.js"></script>
<link href="https://cdn.rawgit.com/knsv/mermaid/6.0.0/dist/mermaid.css" rel="stylesheet" />
<div class='mermaid'>
graph TD;
A(Start)-->B(Do some stuff);
B(Take some rest)-->C(do more);
click B "http://www.github.com" "This is a link"
</div>
You can also do a callback by using this script
<script>
var callback = function(){
alert('A callback was triggered');
}
<script>
and then inserting this into your HTML below node A-->B in your HTML
click A callback "Hi I'm a callback, whats up"
A few diagrams have interaction support:
flowchart
flowDB.js
other usage
classDiagram
classDB.js
gantt
ganttDB.js
This functionality is disabled when using securityLevel='strict'
and enabled when using securityLevel='loose'.
Example
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.14.0/mermaid.min.js"></script>
<h2>FlowChart</h2>
<div class="mermaid">
graph LR
A -- text --> B --> Stackoverflow -- msg --> myLabel2
click Stackoverflow "https://stackoverflow.com/" "some desc when mouse hover" _blank
click myLabel2 "https://stackoverflow.com/" "some desc when mouse hover"
</div>
<h2>classDiagram</h2>
<div class="mermaid">
%% https://github.com/mermaid-js/mermaid/blob/cbe3a9159db4d5e67d270fe701cd63de1510f6ee/docs/directives.md?plain=1#L10-L48
%%{init: {'theme': 'forest'}}%%
classDiagram
class myCls {
attr type
method()
}
%% ↓ must set: securityLevel=loose %% default para: clsID
click myCls call myFunc() "desc."
class myCls2
click myCls2 call myFunc('hello world') "desc."
class myClsUseLink {
+field1
}
link myClsUseLink "https://www.github.com" "This is a link"
</div>
<h2>Gantt</h2>
<div class="mermaid">
gantt
dateFormat HH:mm
axisFormat %H:%M
try to click me : gotoSO, 19:00, 5min
%% click : debug, after gotoSO, 5min --> error, click is "keyword"
clickMe : debug, after gotoSO, 5min
endNode : milestone, m, 20:00, 0min
click gotoSO href "https://stackoverflow.com/"
click debug call myFunc()
%% NOTE: not working on github
</div>
<script>
mermaid.initialize({
securityLevel: 'loose', // strict, loose, antiscript, sandbox // // https://github.com/mermaid-js/mermaid/blob/b141f24068e9c5f6979706383a29db6380ffdf31/docs/usage.md?plain=1#L114-L117
});
function myFunc(arg) {
console.log(arg)
}
</script>
Here's how to hack it into ERD diagrams, which are kinda new so currently lack any kind of clickable support. First create this Javascript object with node names that refer to your intended link destinations:
var links = {
Customer: "/customers/index",
Employee: "/employees/index",
Shipper: "/shippers/index",
OrderDetail: "/order_details/index",
Site: "/sites/index",
User: "/users/index"
};
And then in the Mermaid initializer click events can get wired up to the relevant graphics objects in the SVG with this trickery:
mermaid.initialize({
startOnLoad: true,
securityLevel: "loose",
er: { useMaxWidth: false },
mermaid: {callback: function(objId) {
var svg = document.getElementById(objId);
var nodeName;
for(nodeName in links) {
var gErd = svg.getElementById(nodeName);
gErd.addEventListener("click",
function (evt) {
location.href = links[this.id];
}
);
}
}}
});
If you click anywhere inside the node, it navigates.
I had put all this together for use in The Brick gem, which is a data-related Ruby on Rails add-on.
So I'm essentially wrapping the standard paper-slider element with a custom element, and wanting to include some styling. Below is what I currently have:
<dom-module id="my-slider">
<template>
<style>
/* Works */
paper-slider {
--paper-slider-active-color: red;
--paper-slider-knob-color: red;
--paper-slider-height: 3px;
}
/* Doesn't work */
paper-slider #sliderContainer.paper-slider {
margin-left: 0;
}
/* Also doesn't work */
.slider-input {
width: 100px;
}
</style>
<div>
<paper-slider editable$="[[editable]]" disabled$="[[disabled]]" value="{{value}}" min="{{min}}" max="{{max}}"></paper-slider>
</div>
</template>
<script>
Polymer({
is: "my-slider",
properties: {
value: {
type: Number,
value: 0,
reflectToAttribute: true
},
min: {
type: Number,
value: 0
},
max: {
type: Number,
value: 100
},
editable: Boolean,
disabled: Boolean
}
});
</script>
</dom-module>
JSFiddle: https://jsfiddle.net/nhy7f8tt/
Defining the variables that the paper-slider uses works as expected, but when I try to address anything inside of it directly via its selector, it doesn't work.
I'm fairly new to Polymer, so this may be a very simple/stupid question, but I'm really quite confused and would greatly appreciate any help!
A secondary (but related) issue is the clipping of the input to the right of the editable paper-slider element when the value is 100.
You could use selectors like ::shadow and /deep/ but they are deprecated. If an element doesn't provide the hooks (CSS variables and mixins) then you're basically out of luck.
What you can do, is to create a feature request in the elements GitHub repo to support additional selectors.
Another workaround I already used successfully is to add a style module.
var myDomModule = document.createElement('style', 'custom-style');
myDomModule.setAttribute('include', 'mySharedStyleModuleName');
Polymer.dom(sliderElem.root).appendChild(myDomModule);
I hope the syntax is correct. I use Polymer only with Dart.
The dom-module needs to be a custom-style even though this is normally only necessary when used outside a Polymer element.
See also https://github.com/Polymer/polymer/issues/2681 about issues I run into with this approach.
The following code is working for me,
attached: function(){
var sliderContainer = document.querySelector("#sliderContainer.editable.paper-slider");
sliderContainer.style.marginTop = "5px";
sliderContainer.style.marginBottom = "5px";
},
I want to get an instance of CodeMirror (it is binded to a textarea '#code'). From an onclick-event I want to add a value to the current value of the CodeMirror instance. How can this be achieved? From the docs I can't seem to find anything to get an instance and bind it to a loca var in javascript.
Another method I have found elsewhere is as follows:
//Get a reference to the CodeMirror editor
var editor = document.querySelector('.CodeMirror').CodeMirror;
This works well when you are creating the CodeMirror instance dynamically or replacing an existing DOM element with a CodeMirror instance.
Someone just posted an answer but removed it. Nevertheless, it was a working solution.
Thanks!
-- Basically this was his solution:
// create an instance
var editor = CodeMirror.fromTextArea('code');
// store it
$('#code').data('CodeMirrorInstance', editor);
// get it
var myInstance = $('code').data('CodeMirrorInstance');
// from here on the API functions are available to 'myInstance' again.
There is a getWrapperElement on code mirror editor objects which gives you the root DOM element of the code mirror instance:
var codemirrorDomElem = editor.getWrapperElement();
You can find the instance starting with the <textarea> and moving to the next sibling.
Native
Functional
document.querySelector('#code').nextSibling,
Selector
document.querySelector('#code + .CodeMirror'),
jQuery
Functional
$('#code').next('.CodeMirror').get(0),
Selector
$('#code + .CodeMirror').get(0)
Extra: A more advanced solution involving clipboard.js -> JSFiddle Demo
Example
// Selector for textarea
var selector = '#code';
$(function() {
var editor = CodeMirror.fromTextArea($(selector).get(0), {
mode: 'javascript',
theme: 'paraiso-dark',
lineNumbers : true
});
editor.setSize(320, 240);
editor.getDoc().setValue(JSON.stringify(getSampleData(), null, 4));
$('#response').text(allEqual([
document.querySelector(selector).nextSibling, // Native - Functional
document.querySelector(selector + ' + .CodeMirror'), // Native - Selector
$(selector).next('.CodeMirror').get(0), // jQuery - Functional
$(selector + ' + .CodeMirror').get(0) // jQuery - Selector
]));
});
function allEqual(arr) {
return arr.every(function(current, index, all) {
return current === all[(index + 1) % all.length];
});
};
// Return sample JSON data.
function getSampleData() {
return [
{ color: "red", value: "#f00" },
{ color: "green", value: "#0f0" },
{ color: "blue", value: "#00f" }
];
}
#response { font-weight: bold; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.7.0/codemirror.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.7.0/theme/paraiso-dark.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.7.0/codemirror.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>All equal?: <span id="response"></span></div>
<textarea rows="10" cols="60" id="code"></textarea>
I am using with Vue CLI 3, vue-codemirror component like this:
<codemirror id="textarea_editor" v-model="textarea_input" :options="cm_editor_config"></codemirror>
import codemirror to use within page:
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
and simply add codemirror inside components object, thereafter configuration in data section is:
codemirror_editor: undefined,
cm_editor_config: {
tabSize: 4,
mode: 'application/json',
theme: 'base16-dark',
lineNumbers: true,
// lineWrapping: true,
styleActiveSelected: true,
line: true,
}
and initialized the object in mounted lifecycle section of Vue:
mounted () {
if ( !this.codemirror_editor ) {
this.codemirror_editor = $('#textarea_editor').find('.CodeMirror').get(0).CodeMirror;
}
// do something with this.codemirror_editor
}
Hope this would help many one.
You can simply drop the var: instead of having
var editor = CodeMirror.fromTextArea...
Just have
editor = CodeMirror.fromTextArea...
Then editor is directly available to use in other functions
How can I simulate user-selection of some style from the styles-box, through JS? I want to put some shortcut buttons that assign some of the popular styles with one click.
EDIT:
I don't care if it'll be in-editor button or outer button.
I don't want css-style assignment; I want CKEditor-style assignment (those of the styles-box).
I haven't used CKEditor, but, I saw your question and thought "That would be fun to figure out." Well, here is what I figured out:
(yes, I found terrible documentation, but, that's not the point...I will give them props for commenting their code, though.)
///
// function to add buttons that trigger styles to be applied.
//
// editor - CKEDITOR - instance of editor you want command attached to.
// buttonName - String - name of the button
// buttonLabel - String - humane readable name of the button
// commandName - String - name of command, the way to call this command from CKEDITOR.execCommand()
// styleDefinition - StyleDefinition - obj defining the style you would like to apply when this command is called.
///
var addButtonCommand = function( editor, buttonName, buttonLabel, commandName, styleDefiniton )
{
var style = new CKEDITOR.style( styleDefiniton );
editor.attachStyleStateChange( style, function( state )
{
!editor.readOnly && editor.getCommand( commandName ).setState( state );
});
editor.addCommand( commandName, new CKEDITOR.styleCommand( style ) );
editor.ui.addButton( buttonName,
{
label : buttonLabel,
command : commandName
//adding an icon here should display the button on the toolbar.
//icon : "path to img",
});
};
//Get the editor instance you want to use. Normally the same as the ID of the textarea CKEditor binds to.
var editor1 = CKEDITOR.instances.editor1;
//If you look at ckeditor/_source/plugins/styles/default.js you will see that this selects the first element. That list is read into the array 'default'.
var blueTitleStyle = CKEDITOR.stylesSet.registered.default[0];
//Or, you can define the style like this: See http://dev.ckeditor.com/wiki/Components/Styles for more info on style definitions.
var blueTitleStyle = {
name : 'Blue Title',
element : 'h3',
styles : { 'color' : 'Blue' }
};
addButtonCommand(editor1, 'BlueTitle', 'BlueTitle', 'bluetitle', blueTitleStyle);
Here is a Javascript function to aid your click events:
//function used to execute the command. Only used for calling the command when not calling from a button. (Like an A with an onClick bound to it.)
//pulled this function right out of the api.html example in the ckeditor/_samples dir.
function ExecuteCommand( commandName )
{
// Get the editor instance that we want to interact with.
var oEditor = CKEDITOR.instances.editor1;
// Check the active editing mode.
if ( oEditor.mode == 'wysiwyg' )
{
// Execute the command.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#execCommand
oEditor.execCommand( commandName );
}
else
{
alert( 'You must be in WYSIWYG mode!' );
}
}
Now, you can create a link like this:
<a href='#' class='setBlueTitle'>Set Blue Title</a>
and use a bit of jQuery to spice it up:
<script type="text/javascript">
$(document).ready(function(){
$(".setBlueTitle").onClick(function(e){
//stops the click from changing the page and whatever other default action would happen.
e.preventDefault();
ExecuteCommand('bluetitle');
});
});
</script>
I am not 100% sure about the button icon part. I didn't have an icon to try it with. But, according to a few posts, it should work fine. Regardless, the jQuery click binding works.
That should be pretty much it! I had to do quite a bit of digging around to figure this out, but it certainly is satisfying to see it work!
Here's one option
First, you can setup the desired styles you want to try out in a CSS class. Then, you can set the className for the test div when you click that button. Here's a simple example:
test.css:
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
test.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
<input type="button" onclick="document.getElementById('testStyleDiv').className='bold'" value="bold"/>
<input type="button" onclick="document.getElementById('testStyleDiv').className='italic'" value="italic"/>
<div id="testStyleDiv">foo</div>
</body>
</html>