badicsalex / peginator

PEG parser generator for creating ASTs in Rust
MIT License
34 stars 3 forks source link

feature: support lsp position #8

Closed oovm closed 2 years ago

oovm commented 2 years ago

I need this feature to interact with lsp.

Also I suggest renaming PegPosition::position to offset_range.

Further, I hope that the error can also be converted into lsp diagnostic.

badicsalex commented 2 years ago

I'm pretty sure this could be solved on your side (in the dependent library or binary) with something like this:

pub trait LspOffset {
    fn lsp_range<T>(&self, text: &IndexedText<String>) -> Option<Range>;
    fn lsp_start<T>(&self, text: &IndexedText<String>) -> Option<Position>;
    fn lsp_end<T>(&self, text: &IndexedText<String>) -> Option<Position>;
}

impl<TP:PegPosition> LspOffset for TP {
    fn lsp_range<T>(&self, text: &IndexedText<String>) -> Option<Range> {
        let start = self.lsp_start(&text)?;
        let end = self.lsp_end(&text)?;
        Some(Range { start, end })
    }

    fn lsp_start<T>(&self, text: &IndexedText<String>) -> Option<Position> {
        let pos = text.offset_to_pos(self.position().start)?;
        text.pos_to_lsp_pos(&pos)
    }

    fn lsp_end<T>(&self, text: &IndexedText<String>) -> Option<Position> {
        let pos = text.offset_to_pos(self.position().end)?;
        text.pos_to_lsp_pos(&pos)
    }
}

This use-case is exactly why I made it a trait. The error conversion should also remain in your peginator + lsp library. I'd like to have only core PEG code in peginator, with as little dependencies (even optional ones) as possible.

I will consider renaming position to offset. I'll have to sleep on it though.

oovm commented 2 years ago

Oh, I will make it on my side