Draft-js: replace ContentBlock with a fragment - draftjs

I have reference on some ContentBlock(that not selected). How can i replace it with some fragment?
I have some fragment
const fragment = DraftPasteProcessor.processHTML(html);
And reference on block
const currentBlock = content.getBlockForKey(myKey);
How can i replace this block with a fragment. This block is not selected. I wan't to replace it and set cursor in the end of fragment.
I tried to use Modifier.replaceWithFragment, but this method works only with SelectedState.

The easiest way to do this is to move the selection, then delete the fragment:
const fragment = DraftPasteProcessor.processHTML(html);
const myKey = 'some id'; // same as your code
const currentBlock = content.getBlockForKey(myKey);
const anchorOffset = currentBlock.getLength();
const selection = SelectionState.createEmpty(myKey).set('anchorOffset', anchorOffset);
Modifier.replaceWithFragment(content, selection, fragment);
This is a pretty common type of action to take with DraftJS. You'll notice on the DraftJS docs that it tells you to use the ImmutableJS functions (set in this case) to modify your selection as needed.

Related

how to make snippets auto complete in my custom vs code extension?

im korean beginner developer... help... T^T
i want to make auto complete like snippets in my custom vs code extension.
now my code,
const snippetBase = `axios.({
url: "${service.url}",
method: "${service.description}",
`
const editor = vscode.window.activeTextEditor
const selection: any = editor?.selection
editor?.edit(builder => {
builder.replace(
selection,
snippetBase + snippetHeaders(snippetRes.data.header) + snippetBody(snippetRes.data.body)
)
})
then, my extension auto complete image
I want to focus my cursor automatically inside the format after the snippet is shown.
Just like picture below.
snippets image
help me plz!!
It sounds from your comment that you want the edit to act as a snippet. Then you need to make a SnippetString and use the editor.insertSnippet() command which can take that SnippetString as an argument. This should work for you:
const editor = vscode.window.activeTextEditor
const selection = editor?.selection
const axiosSnippet = new vscode.SnippetString("axios.({\n")
axiosSnippet.appendText("\turl: \"")
axiosSnippet.appendPlaceholder(service.url)
axiosSnippet.appendText("\",\n")
axiosSnippet.appendText("\tmethod: \"")
axiosSnippet.appendPlaceholder(service.description)
axiosSnippet.appendText("\",\n")
editor.insertSnippet(axiosSnippet, selection)
axiosSnippet.appendPlaceholder(service.url); is the key to this, as it will select that placeholder first and then allow you to tab to the next placeholder axiosSnippet.appendPlaceholder(service.description).
[I don't know the structure of the rest of your snippet,e.g., snippetHeaders(snippetRes.data.header). If it is just text than you can use the appendText method with \n for newlines.

In DraftJs How to re adjust the cursor after setting the state via decorator and strategy?

Problem: Loses focus when selected the hash tag.
Example: type #on and select any tag the editor is losing the focus.
In above codepen: how can I add/retain cursor after the hash tag?
Following this article
https://bigbite.net/2017/12/13/building-editor-draft-js-react/
Code from this article.
https://codepen.io/bigbite/pen/gXNOvz
I've to add that in my own use case.
UC: While editing the content in editor when user presses the key combination then show a dropdown, which will contain the custom react component name, and user will be able to select the custom component and it will add that component via decorator and strategy.
It has been achieved but the editor loses its focus at the same time.
I can achieve the focus via ref this.editor.focus() but shows the cursor at the start of the editor.
const addEntityAndComponent = (editorState, content) => {
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
const contentStateWithEntity = contentState.createEntity(content, 'IMMUTABLE', { content });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newContentState = Modifier.insertText(contentStateWithEntity, selection, content, null, entityKey);
const newEditorState = EditorState.push(editorState, newContentState);
return EditorState.forceSelection(newEditorState, newContentState.getSelectionAfter());
};
I'm using the lib to achieve the functionality.
https://github.com/jpuri/react-draft-wysiwyg/
Here is my code.
https://github.com/iozeey/react-draft-wysiwyg-custom-component
Hope it will be helpful.
Followed this doc.
https://draftjs.org/docs/advanced-topics-managing-focus
Tried solution from here but did not work.
https://draftjs.org/docs/api-reference-editor-state#movefocustoend
I was using this package.
https://github.com/jpuri/react-draft-wysiwyg/blob/master/src/Editor/index.js#L348
My solution was to reset the cursor position after focusing the editor.
focus() {
const se = this.state.editorState.getSelection();
this.editor.focus();
this.setState({
editorState: EditorState.forceSelection(this.state.editorState, se),
});
}

Vscode Extension how to grab values of variable

Looked everywhere but unsure how to accomplish this feat. I'm looking to do something like this. When a user types something like this:
const hi = 'hello world';
#generate(hi)
and the user highlights #generate(hi), the user can run a set command. This command is written like this in the extension:
const generateCodeCommand = vscode.commands.registerCommand('extension.generateCode', () => {
const editor = vscode.window.activeTextEditor;
if (editor) {
const document = editor.document;
const selection = editor.selection;
// get the word within the selection
const word = document.getText(selection);
console.log('this is the word', word);
}
});
Here I've managed to grab the word '#generate(hi)' but I'm looking to grab the string 'hello world' through the 'hi' reference. Is there a particular way to do this?

Set cursor location in CompletionItem

I want to add numbers to the sass-indentation extension and I kind of figured out how to that, it would be nice if i could set the cursor location when the suggestion gets triggered, just like you can set the cursor location when you make snippets with $1, is that possible ?
import { CompletionItem, CompletionItemKind } from 'vscode';
const sassSchemaTest = [
{
name: '%',
body: '$1%', // I want the cursor location where the '$' sign is
description: 'test'
}
];
export default sassSchemaTest.map(item => {
const completionItem = new CompletionItem(item.name);
completionItem.insertText = item.body;
completionItem.detail = item.description;
completionItem.kind = CompletionItemKind.Property;
return completionItem;
});
Yes, completion items support the usual snippet syntax. Simply use a vscode.SnippetString for insertText instead of a raw string.
A string or snippet that should be inserted in a document when selecting this completion. When falsy the label is used.
completionItem.insertText = new vscode.SnippetString(item.body);

Draft.js: How to build ContentBlock with type atomic?

I define a blockRendererFn callback to render a block with my own defined component. But How can I build the editor with existing content? Constructor of ContentBlock has no option to accept my component
Constructor of ContentBlock has no option to accept my component
You can pass your custom component name to type property of ContentBlock configuration object.
For example, we have a custom component with MyCustomBlock name. And we have an array of strings, that you want to wrap in the custom component and show as an existing content of the editor. Create an array of ContentBlocks this way:
const input = ['foo', 'bar', 'baz'];
const contentBlocksArray = input.map(word => {
return new ContentBlock({
key: genKey(),
type: 'MyCustomBlock',
characterList: new List(Repeat(CharacterMetadata.create(), word.length)),
text: word
});
});
and get initial editor state with EditorState.createWithContent and ContentState.createFromBlockArray methods:
this.state = {
editorState: EditorState.createWithContent(ContentState.createFromBlockArray(contentBlocksArray))
};
Look at this working example - http://jsfiddle.net/levsha/vp8utkwv/