Giter Site home page Giter Site logo

Comments (4)

nightwing avatar nightwing commented on July 29, 2024

Could you tell a bit more about your usecase, and show what the fn function is meant to do.

I am worried that alterOperator above would expose too much internal details in public api, but maybe i am wrong, or maybe we can work together to find a better/easier to maintain api for your usecase.

from codemirror-vim.

brendanbond avatar brendanbond commented on July 29, 2024

Thanks @nightwing!

TLDR; this API would boil down to

  1. get ranges before they're passed to the operator fn
  2. add offset to ranges if necessary
  3. pass new range value to the operator fn

and could be useful for cases in which a CM instance might want to "tweak" the behavior of an operator without ripping it out and starting from scratch.

Full use case:
The application uses delimiter text (with the grammar "\n<delemiter>\n") that is parsed and replaced with a widget to implement a "block" system:

this is a block, the line below is delimiter text that will be replaced with a visual widget (e.g. a styled horizontal line)
∞∞∞markdown
here is another block

If I am in insert mode and use the backspace key to delete line 3, the widget is removed and the cursor moves to the end of line 1:

this is a block, the line below is delimiter text that will be replaced with a visual widget (e.g. a styled horizontal line)

But if I am in normal mode and use the 'dd' linewise delete operator, I blow up the delimiter grammar by removing the second newline character, and the delimiter text is no longer parsed and replaced. Instead, the text is visible to the user:

this is a block, the line below is delimiter text that will be replaced with a visual widget (e.g. a styled horizontal line)
∞∞∞markdown

The same is true for operators like d/m or :%s/markdown/javascript/g (in that they operate on the delimiter text) because they are not "aware" of the delimiter text. Rather than completely reimplement operators from scratch using defineOperator, it would be kind of nice to introduce the ability to add offsets to the range argument(s) passed to an operator using something like the intermediate function above that would return a new range (or, more likely in practice, a new set of operator arguments):

    // psuedocode from the application
    Vim.alterOperator('delete', function(cm, prevArgs, prevRanges, prevOldAnchor, prevNewHead) {
        let state = editor.view.viewState.state;
        const doc = state.doc;
        const cm6Ranges = prevRanges.map((range) => convertToCM6Range(range.anchor, range.head, doc));
        const activeBlock = getActiveBlock(state);
        let newRanges = prevRanges;
        if (cm6Ranges.contains(activeBlock.delimiter)) {
            newRanges = addDelimiterOffset(prevRanges, activeBlock.delimiter);
        }

        return newRanges;
    });

I didn't want to start implementing this without knowing if there was any appetite for this type of API, so this obviously could be cleaned up quite a bit and fit to your liking. It has the advantage of being completely opt-in and inverting control to the library user, so I don't see any risk of exposing too much of the library internals, but that is certainly your call to make. Let me know if you have any thoughts/suggestions!

from codemirror-vim.

nightwing avatar nightwing commented on July 29, 2024

Wouldn't it be simpler to use codemirror's EditorState.changeFilter api to prevent changes from destroying blocks? That way just one function should be able to handle all the cases, instead of having to call alterOperator on unknown number of operators and having to change your code when vim mode implements some new commands that are able to delete text?

from codemirror-vim.

brendanbond avatar brendanbond commented on July 29, 2024

It's funny you mention this because, after my inquiry this morning, I was looking at just such a solution. Thanks for the info! I'll close this for now

from codemirror-vim.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.