I’d like to replace the triple-` code block shortcut with our CodeMirror widget. Here is our widget schema and autoInput rule :
import {InputRule} from 'prosemirror/src/inputrules'
import {Media} from '../schema/media'
import uuid from 'uuid'
Media.register('autoInput', 'replaceWithCodeWidget',
new InputRule(/^```$/, '`', function (pm, _, pos) {
pm.tr.replaceWith(pos, pos, pm.schema.node(this, {
id: uuid.v4(),
type: 'code'
})).apply()
})
)
(updated for 0.2.0 changes)
On typing the shortcut, the code runs without errors, but the document doesn’t change, and p isn’t replaced with the widget placeholder. Any clues?
Something changes, if I hit delete after the 3 `s the whole paragraph is deleted.
Also tried the setBlockType
method used in the PM code autoinput, but it doesn’t work. Maybe something is wrong with the div schema def ?
Media.register('autoInput', 'replaceWithCodeWidget',
new InputRule(/^```$/, '`', function (pm, _, pos) {
setAs(pm, pos, this, {
id: uuid.v4(),
type: 'code'
})
})
)
function setAs (pm, pos, type, attrs) {
pm.tr.setBlockType(pos, pos, type, attrs)
.delete(new Pos(pos.path, 0), pos)
.apply()
}
marijn
February 3, 2016, 3:22pm
3
You can’t pass the cursor position to setBlockType
. It takes the position before the block as argument. Calling pos.shorten()
might help.
CodeBlock and Heading autoinput use pos
the same way that I’m trying to here.
If I change Media.register
to Heading.register
it works to convert to h1.
I’ve tried all combinations of replaceWith, setBlockType, and setNodeType with pos and pos.shorten(). I’m suspecting something in the Media (div) schema is silently blocking the conversion.
marijn
February 3, 2016, 7:05pm
5
Ah, my bad, I was thinking of setNodeType
not setBlockType
.
That does indeed look like it should work. Could it be that your Media
type isn’t allowed in the place where the old block is? What’s its kind
?
I want it to only be a top-level block:
export class Media extends Block {
static get kinds () { return 'doc media' }
...
marijn
February 4, 2016, 1:34pm
7
That probably doesn’t do what you intend for it to do. The strings in kinds
will be compared to the contains
fields in parent nodes. I don’t think you have a parent node that contains "media"
or "doc"
.
You could give your doc
node a contains
of "toplevel"
and add everything that may appear at the top level to that. And for nestable nodes that may also appear on the toplevel, give them kinds
"toplevel block"
, for example.
Changing to static get kinds () { return 'block' }
didn’t help.
marijn
February 16, 2016, 2:44pm
9
Could you put up a (minimal) script that shows the problem somewhere? I can’t really guess what is going on from the hints you’re providing.
Current version that works with our custom code editor (CodeMirror iframe):
import {Media} from '../schema/media'
import uuid from 'uuid'
import {InputRule} from 'prosemirror/src/inputrules'
Media.register('autoInput', 'ed_start_code',
new InputRule(/^```$/, '`', function (pm, _, pos) {
insertBlock(pm, pos, this, {id: uuid.v4(), type: 'code'})
})
)
function insertBlock (pm, pos, type, attrs) {
const $pos = pm.doc.resolve(pos)
const start = pos - $pos.parentOffset
const nodePos = start - 1
const codeNode = type.create(attrs)
pm.tr
// delete the ```
.delete(start, pos)
// insert the code block above the current block
.insert(nodePos, codeNode)
.apply()
}
1 Like