0

I am new to WPF and currently I am studying to create a Sublime Text that has syntax highlighting. I come to a challenge in figuring out the TextRange of word at current caret position (Not include symbols e.g: for( will return the whole word instead of for only). More over because already solutions are checking the whole file which could be reduce the performance considerably. Are there any solution for this problems thank you! Below is my code

private TextRange getCurrentWordRange()
    {
        
        List<string> spaces = new List<string> { " ", "\t" ,";","(", ")", "=" };
        List<string> symbols=new List<string>{};

        TextPointer current = richTextBox.CaretPosition;
        TextPointer start = current, end = current;

        //Traverse to get the start of word
        while (start.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text)
        {
            TextRange textRange = new TextRange(start.GetPositionAtOffset(-1), start); // get the textRange of the previous start

            if (spaces.Any(token => textRange.Text.Contains(token))) // check if textRange.Text has token that inside spaces
                break;
            else
                start = start.GetPositionAtOffset(-1);
            
        }


        //Traverse to get the end of word
        while(end.GetPointerContext(LogicalDirection.Forward)==TextPointerContext.Text)
        {
            TextRange textRange = new TextRange(end,end.GetPositionAtOffset(1)); // get the textRange of the next start
            
            if (spaces.Any(token => textRange.Text.Contains(token)))
                break;
            else
                end = end.GetPositionAtOffset(1);
        }
        
        return new TextRange(start,end);
    }

EDIT Fortunately, I rethink and writing the below code that might be success in the case. Hope anyone can check if it is correct. Thank you.

    private TextRange getCurrentWordRange()
        {
            List<string> spaces = new List<string> { " ", "\t" };
            List<string> symbols = new List<string> { ";", "(", ")", "=", "<", ">", "\"", ",", ".", "[", "]", ":" };
            TextPointer current = richTextBox.CaretPosition;
            TextPointer start = current, end = current;
            TextRange backward;
            TextRange forward;

            // check if start and end are not the Content.Start and Content.End
            if (start.GetPositionAtOffset(-1) == null)
                backward = new TextRange(start, start);
            else
                backward = new TextRange(start.GetPositionAtOffset(-1), start);

            if (end.GetPositionAtOffset(1) == null)
                forward = new TextRange(end, end);
            else
                forward = new TextRange(end, end.GetPositionAtOffset(1));



            while (!spaces.Contains(backward.Text) && start.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text && !symbols.Contains(backward.Text))
            {
                start = start.GetPositionAtOffset(-1);
                backward = new TextRange(start, start.GetPositionAtOffset(-1));
            }
            while (!spaces.Contains(forward.Text) && end.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text && !symbols.Contains(forward.Text))
            {
                end = end.GetPositionAtOffset(1);
                forward = new TextRange(end, end.GetPositionAtOffset(1));
            }

            // if between start and end is "" then consider add a left adjacent or right adjacent symbol for further development
            if (new TextRange(start, end).Text == "")
            {
                if (symbols.Contains(backward.Text))
                {
                    start = start.GetPositionAtOffset(-1);
                }
                else if (symbols.Contains(forward.Text))
                {
                    end = end.GetPositionAtOffset(-1);
                }
            }

            return new TextRange(start, end);
}

Capture

I created a TextChanged Event for RTB then perform few functions to check and highlight keyword It work great with @Jackdaw solution but stuck at that case again

Hoang Thinh
  • 111
  • 1
  • 12
  • You could use Regex, but you will either pass to it the entire text again, or you will still have to find start and end indexes yourself. – o_w Dec 28 '20 at 10:25
  • For highlighting purpose, it would be time consuming if i pass the text while Text is changed. I think I should do it by myself instead. Anyway thank you – Hoang Thinh Dec 29 '20 at 09:19
  • @Totomaru: Look at the following post: [https://stackoverflow.com/a/66187764/6630084](https://stackoverflow.com/a/66187764/6630084). – Jackdaw Feb 13 '21 at 22:21
  • @Totomaru: The function above `getCurrentWordRange()` will not work correctly when words have partial formatting. But the `GetEdgeTextPointer()` function from the [https://stackoverflow.com/a/66187764/6630084](https://stackoverflow.com/a/66187764/6630084) post is supporting the partial formatting also. – Jackdaw Feb 13 '21 at 22:45
  • @Jackdaw thank you I will check it if there is a solution for this. – Hoang Thinh Mar 01 '21 at 11:04
  • @Totomaru: Any further question on your post is welcome! :) – Jackdaw Mar 01 '21 at 16:14

0 Answers0