Closed abulka closed 3 years ago
Currently the Codemirror instance that is used by the script editor isn't exposed, I think exposing it will allow for most of the stated customizations, getPreContent and getPostContent have been on the roadmap for implementation so I'll also look into them.
Actually you can get the CodeMirror
instance by using:
editor.Commands.get('edit-script').getCodeViewer()
As of CodeMirror
itself I'm not sure if it's exposed by grapesjs
, if it's not then you can request that on the main repo.
Edit: Looks like CodeMirror
isn't exposed: https://github.com/artf/grapesjs/blob/dev/src/code_manager/model/CodeMirrorEditor.js
For reference getPreContent
and getPostContent
are also already implemented, these functions must return a string
or HTMLElement
:
pluginsOpts: {
'grapesjs-script-editor': {
commandAttachScript: {
getPreContent() {},
getPostContent() {}
}
}
Thanks, getting the CodeMirror
instance like that worked, though the actual cm
instance needs .editor
thus
let cm = editor.Commands.get('edit-script').getCodeViewer().editor
This will add a button to the script-editor
getPreContent() {
return '<p>Snippets</p><button id="snippet1">snippet1</button><p></p>'
},
this code inside showCustomCode(target)
will then hook up that snippet button to change the script-editor contents
const snippet1 = '...'
document.getElementById('snippet1').addEventListener('click', function () {
cm.setValue(snippet1)
})
I still need to get to the Codemirror
object in order to access things like CodeMirror.Pos
so that I can do more advanced snippets, but this is a great start!
Awesome stuff, you can also add the events within getPreContent
:
getPreContent() {
const btn = editor.$('<p>Snippets</p><button id="snippet1">snippet1</button><p></p>');
btn.find('snippet1').click(function() {
//...
});
//or
btn.find('snippet1').on('click', function() {
//...
});
return btn.get(0);
},
For Codemirror
itself you can ask for it to be exposed on the main repo https://github.com/artf/grapesjs or import the library yourself.
Would appreciate any thoughts on the first half of this issue?
"Can you advise on how to use codemirror addons within the grapesjs-script-editor esp. the commenting command?"
I can't get commenting to work, for example.
Seems to me the addons are imported correctly so maybe those addons are deactivated by default so try making them active:
codeViewOptions: {
//...
toggleComment: true,
commentRange: true,
//...
},
I added those enabling lines but it made no difference. I made a minimal https://jsfiddle.net/tcab/hzngLb6o/
I've tried tracing into codemirror but its pretty hairy in there... I think the commands aren't being found for some reason.
Unfortunately, I'm not really sure as this issue is a bit complicated to debug, maybe cm.execCommand('...')
is not the proper way of invoking such extensions, given they are not built into Codemirror
In past projects I've found that either of these techniques work:
'Cmd-/': function (cm) { cm.execCommand('toggleComment') }, // technique 1
'Cmd-1': function (cm) { cm.toggleComment() }, // technique 2
however it seems you are right re invoking the Grapesjs bundled commentRange
- it must be done using technique 2 and not via cm.execCommand
. Furthermore, it takes parameters. Thus I was able to get some commenting working, as long as you select the area you want commented:
'Cmd-1': function (cm) { cm.commentRange(true, cm.getCursor(true), cm.getCursor(false)) }, // comment
'Cmd-2': function (cm) { cm.commentRange(false, cm.getCursor(true), cm.getCursor(false)) }, // uncomment
I've created an issue at Grapesjs https://github.com/artf/grapesjs/issues/3286 - perhaps someone there can help further with 3rd party add-ons esp. re exposing the CodeMirror
function itself, which as you say, is not currently exposed and is needed for lots of things, including calls like CodeMirror.Pos
and CodeMirror.cmpPos
etc.
Come to think of it, I wonder if importing Codemirror
ourselves and avoiding the built in codemirror would be possible? Then we would have full control and be able to use all the add-ons in the script editor like auto-complete etc!
I think importing Codemirror
ourselves is possible, using the built in version just helps us avoid importing the same library twice.
I want to add extra shortcut keys to invoke codemirror addons whilst using grapesjs-script-editor. I also want to be able to programmatically insert text into the the script editor.
cm
andCodemirror
objects from anywhere in my application code?Details
Add-ons
Since this plugin exposes a
codeViewOptions
object I tried to add some extra shortcut keys e.g. for commenting out lines and duplicating lines etc.Whilst the hotkeys are triggering ok, the commands are not working - failing because the specified commands don't exist?
I tried importing
<script src="node_modules/codemirror/addon/comment/comment.js"></script>
but am wondering if this has any effect since Grapesjs seems to get its extra codemirror commands from some special modulehttps://github.com/artf/codemirror-formatting/blob/master/formatting.js
.Can you advise on how to use codemirror addons within the grapesjs-script-editor esp. the commenting command?
Accessing
CodeMirror
I also want to define a duplicate line command which I got from https://github.com/codemirror/CodeMirror/blob/master/keymap/sublime.js#L327 but which requires access to the Codemirror object e.g.
CodeMirror.commands
andCodeMirror.Pos
- is there any way to get toCodemirror
?Accessing the codemirror instance
cm
Finally, I want to add UI elements to the top of the script editor, which I can happily do with e.g.
I plan to add listener functions to those buttons to insert script fragments and examples into the script editor using codemirror functions like
I even have a cool function to insert text at the current cursor position
Can I get access to
cm
from my listener which would be defined as part ofgetPreContent()
? That would be so powerful!