uiwjs / uiwjs/react-codemirror

Cannot dynamically select code

Open
#509 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.3k
Forks
161
PR merge metrics
No merged PRs in 30d

Description

Hi,

I'm implementing a debugger for which I need to select a portion of the code dynamically: essentialy whenever the user steps over the code I need to select the sentence to be executed. Here is the editor rendering code:

...
<CodeMirror
	ref={this.editorRef}
	width="100%"
	height="100%"
	extensions={[
		smalltalk,
		EditorView.lineWrapping,
		lintGutter(),
		linter(this.annotations),
		Prec.highest(keymap.of([...this.extraKeys()])),
	]}
	theme={this.theme()}
	value={source}
	onChange={this.sourceChanged}
	readOnly={evaluating || progress}
	basicSetup={{
		lineNumbers: lineNumbers,
		closeBrackets: true,
		bracketMatching: true,
		highlightActiveLine: false,
		drawSelection: true,
	}}
/>
...

where source is part of the state.
The component is provided with a 'selectedRange' prop, and it works fine except for the first time. Since there is no option to set the selection in the same way as the value, I have to manage it somewhere else: I did it in componentDidUpdate thinking (naively perhaps) that I needed to have the value updated in order to apply the new selection. Concretely, I have this function:

selectRange(range) {
		try {
			this.editorRef.current.editorView.dispatch({  selection: range });
		} catch (error) {
			console.log(error);
		}
}

and I call it from componentDidUpdate.
The point is when selectRange is called, the value of the editor hasn't change yet... it changes a bit after, so the range can fall ouside of the (previous) value.
For example, lets suppose that the current code is:

someCode
   self someOtherCode

And the the user changes to a frame (remember that it is a debugger, with a call stack with different frames/methods) where the new code is:

someOtherCode
    self blah.
    self blahBlah.
    self blahBlahBlah.

and the selection in the new code should be [anchor: 54, head: 75].
The render call will set the value to the new code but then when componentDidUpdate is called, it will try to apply the selection to the current value (....viewState.state.doc), which is still the previous code, and then the selection transaction will fail.
Any suggestion? Any other way to manage the selection in a "controlled" way?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the CodeMirror component ref, the source prop/state update, and the componentDidUpdate-to-selectRange flow shown in the issue. Check when the editor value and editorView state are updated relative to dispatching the selection. Done means switching to a new frame applies the requested range without a transaction failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.