Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature for moving the current block up and down #204

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

wolimst
Copy link

@wolimst wolimst commented Feb 20, 2024

Support moving the current block up and down with keyboard shortcuts.

Closes #37.

@wolimst
Copy link
Author

wolimst commented Feb 20, 2024

**ISSUE RESOLVED**

@heyman Hello! I've implemented block moving feature requested in #37, but currently have a problem. Want to hear any ideas about the problem!

Currently, moving a block up and down works when it is not related to the first block of the buffer.

For example, as you can see in below example, moving the 2nd block down works, however, moving the 2nd block up is removing the content of the 1st block and the 2nd block. Same problem happens when moving the 1st block down. There is no problem when the moving block up or down, when the 1st block is not contained in the moving process.

∞∞∞text-a               ∞∞∞text-a
1st block               1st block
∞∞∞text-a   -------->   ∞∞∞text-a
2nd block   move down   3nd block
∞∞∞text-a               ∞∞∞text-a
3nd block               2nd block   <- works fine

======================================================================

∞∞∞text-a               ∞∞∞text-a
1st block                           <- 1st & 2nd block disappears
∞∞∞text-a   -------->   ∞∞∞text-a
2nd block    move up    3rd block
∞∞∞text-a               
3nd block               

I'm using following code to update the block ordering,

    dispatch(state.update({
        changes: {
            from: up ? neighborBlock.delimiter.from : currentBlock.delimiter.from,
            to: up ? currentBlock.content.to : neighborBlock.content.to,
            insert: newContent,
        },
        selection: newSelectionRange,
    }

and when moving the 2nd block up (or moving the 1st block down), it become something like this:

    dispatch(
        state.update({
            changes: {
                from:   0,
                to:     "\n∞∞∞text-a\n1st block\n∞∞∞text-a\n2st block".length,
                insert: "\n∞∞∞text-a\n2nd block\n∞∞∞text-a\n1st block",
            },
        }),
    )

The changes part seems ok to me, and I don't understand what is happening for now. Any ideas?

@wolimst
Copy link
Author

wolimst commented Feb 20, 2024

**ISSUE RESOLVED**

Also, I found below example which I think is simpler example related to the above problem.

    dispatch(
        state.update({
            changes: {
                from: 0,
                to: "\n∞∞∞text-a\n012345".length,
                insert: "\n∞∞∞text-a\n012345",
            },
        }),
    )

Running above code on the below left buffer should not change the buffer, however, it removes some text and changes the buffer to the right one.

∞∞∞text-a    ---->    ∞∞∞text-a
0123456789            6789

@wolimst
Copy link
Author

wolimst commented Feb 20, 2024

I'll try to add some tests too!

Also, I want to hear about the keyboard shortcuts. I've set Ctrl+Alt+Shift+Up/Down for now, since all other combinations of modifiers are already used as below.

  • Ctrl+Up/Down: moving cursor to previous/next block
  • Alt+Up/Down: moving the current line up/down
  • Shift+Up/Down: extend cursor range to previous/next line
  • Ctrl+Shift+Up/Down: extend cursor range to previous/next block
  • Alt+Shift+Up/Down: copying the current line up/down
  • Ctrl+Alt+Up/Down: create new cursor up/down

@wolimst
Copy link
Author

wolimst commented Feb 22, 2024

Ah, found what was causing it. Added an annotation to ignore the filter.

const preventFirstBlockFromBeingDeleted = EditorState.changeFilter.of((tr) => {
//console.log("change filter!", tr)
const protect = []
if (!tr.annotations.some(a => a.type === heynoteEvent) && firstBlockDelimiterSize) {
protect.push(0, firstBlockDelimiterSize)
}
// if the transaction is a search and replace, we want to protect all block delimiters
if (tr.annotations.some(a => a.value === "input.replace" || a.value === "input.replace.all")) {
const blocks = tr.startState.facet(blockState)
blocks.forEach(block => {
protect.push(block.delimiter.from, block.delimiter.to)
})
//console.log("protected ranges:", protect)
}
if (protect.length > 0) {
return protect
}
})

@wolimst wolimst marked this pull request as ready for review February 25, 2024 06:38
@BoscoDomingo
Copy link

@heyman Any chance you could review this one?

@heyman
Copy link
Owner

heyman commented Apr 12, 2024

Hey! I'm swamped with other work at the moment, but I plan to get to it soon.

@BoscoDomingo
Copy link

Hey! I'm swamped with other work at the moment, but I plan to get to it soon.

Totally understandable. Thank you for your work and don't sweat it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FR: Move / re-order blocks?
3 participants