Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. QtCreator plugin: syntax highlighting resets document format
Forum Updated to NodeBB v4.3 + New Features

QtCreator plugin: syntax highlighting resets document format

Scheduled Pinned Locked Moved Unsolved Qt Creator and other tools
5 Posts 3 Posters 465 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vladimir Looze
    wrote on last edited by
    #1

    Problem

    I am writing AI-assistant plugin for QtCreator. As part of this plugin I need to show code completion suggestion, which can be multiline.
    I am attempting to show AI-suggestion as code inline and then de-highlight it using custom QSyntaxHighlighter, it works fine in regular QTextEdit, but if I apply this to QtCreator's editor, then all formatting in QTextDocument resets to plain-text (i.e. all C++ coloring reverts to "regular text" with excepton of a few class names).

    Here is how it looks normally and with my highlighter:
    highlight.png

    Attempted solutions

    To achieve this I subclassed QSyntaxHighlighter and written simple range-matching code that would grey-out part of QTextDocument from highlight_start to highlight_end

    I have tried inserting html tags around AI-suggestion, it works, but not 100% of the time. Sometimes QtCreator's highlighter re-highlights suggested code snippet which I have no control over.

    I have tried doing nothing in highlightBlock function, and formatting still resets.

    Code

    Highlighter Class definition looks like this:

    class CompletionHighlighter : public QSyntaxHighlighter
    {
        Q_OBJECT
    
        QTextCharFormat completionFormat;
        int highlight_start;
        int highlight_end;
    public:
        CompletionHighlighter(QTextDocument *parent = 0);
    public slots:
        void setCompletionPosition(int start, int end);
    protected:
        void highlightBlock(const QString &text) override;
    };
    

    Simple implementation looks like this

    #include "completion_highlighter.h"
    
    CompletionHighlighter::CompletionHighlighter(QTextDocument *parent)
        : QSyntaxHighlighter(parent)
    {
        completionFormat.setForeground(Qt::gray);
    }
    
    void CompletionHighlighter::setCompletionPosition(int start, int end)
    {
        highlight_start = start;
        highlight_end = end;
    }
    
    void CompletionHighlighter::highlightBlock(const QString &text)
    {
        int block_highlight_start = std::min(
            std::max(highlight_start - currentBlock().position(), 0), currentBlock().length() - 1);
        int block_highlight_end = std::min(
            std::max(highlight_end - currentBlock().position(), 0), currentBlock().length() - 1);
        if (block_highlight_start == block_highlight_end) {
            return;
        }
        setFormat(block_highlight_start, block_highlight_end-block_highlight_start, completionFormat);
    }
    

    To use this highlighter I get current QtCreator's editor with

    Core::IEditor *editor = Core::EditorManager::currentEditor();
    QPlainTextEdit *plain_text_edit = qobject_cast<QPlainTextEdit *>(editor->widget());
    

    and then create highlighter class with

    new CompletionHighlighter(plain_text_edit->document());
    

    Any ideas how I can highlight part of code without affecting entire document?

    V 1 Reply Last reply
    0
    • Christian EhrlicherC Christian Ehrlicher moved this topic from General and Desktop on
    • V Vladimir Looze

      Problem

      I am writing AI-assistant plugin for QtCreator. As part of this plugin I need to show code completion suggestion, which can be multiline.
      I am attempting to show AI-suggestion as code inline and then de-highlight it using custom QSyntaxHighlighter, it works fine in regular QTextEdit, but if I apply this to QtCreator's editor, then all formatting in QTextDocument resets to plain-text (i.e. all C++ coloring reverts to "regular text" with excepton of a few class names).

      Here is how it looks normally and with my highlighter:
      highlight.png

      Attempted solutions

      To achieve this I subclassed QSyntaxHighlighter and written simple range-matching code that would grey-out part of QTextDocument from highlight_start to highlight_end

      I have tried inserting html tags around AI-suggestion, it works, but not 100% of the time. Sometimes QtCreator's highlighter re-highlights suggested code snippet which I have no control over.

      I have tried doing nothing in highlightBlock function, and formatting still resets.

      Code

      Highlighter Class definition looks like this:

      class CompletionHighlighter : public QSyntaxHighlighter
      {
          Q_OBJECT
      
          QTextCharFormat completionFormat;
          int highlight_start;
          int highlight_end;
      public:
          CompletionHighlighter(QTextDocument *parent = 0);
      public slots:
          void setCompletionPosition(int start, int end);
      protected:
          void highlightBlock(const QString &text) override;
      };
      

      Simple implementation looks like this

      #include "completion_highlighter.h"
      
      CompletionHighlighter::CompletionHighlighter(QTextDocument *parent)
          : QSyntaxHighlighter(parent)
      {
          completionFormat.setForeground(Qt::gray);
      }
      
      void CompletionHighlighter::setCompletionPosition(int start, int end)
      {
          highlight_start = start;
          highlight_end = end;
      }
      
      void CompletionHighlighter::highlightBlock(const QString &text)
      {
          int block_highlight_start = std::min(
              std::max(highlight_start - currentBlock().position(), 0), currentBlock().length() - 1);
          int block_highlight_end = std::min(
              std::max(highlight_end - currentBlock().position(), 0), currentBlock().length() - 1);
          if (block_highlight_start == block_highlight_end) {
              return;
          }
          setFormat(block_highlight_start, block_highlight_end-block_highlight_start, completionFormat);
      }
      

      To use this highlighter I get current QtCreator's editor with

      Core::IEditor *editor = Core::EditorManager::currentEditor();
      QPlainTextEdit *plain_text_edit = qobject_cast<QPlainTextEdit *>(editor->widget());
      

      and then create highlighter class with

      new CompletionHighlighter(plain_text_edit->document());
      

      Any ideas how I can highlight part of code without affecting entire document?

      V Offline
      V Offline
      Vladimir Looze
      wrote on last edited by
      #2

      Simple experiment with two QSyntaxHighlighter shows that last one overrides whatever changes is made by previous ones. In order to add my highlights to whatever is already highlighted I need to call setFormat with all existing formatting somehow.

      V 1 Reply Last reply
      0
      • V Vladimir Looze

        Simple experiment with two QSyntaxHighlighter shows that last one overrides whatever changes is made by previous ones. In order to add my highlights to whatever is already highlighted I need to call setFormat with all existing formatting somehow.

        V Offline
        V Offline
        Vladimir Looze
        wrote on last edited by
        #3

        I've found the "solution", there is a way to apply all previous formats in a block:

        for(QTextLayout::FormatRange &range : currentBlock().layout()->formats()) {
          setFormat(range.start, range.length, range.format);
        }
        

        One would think, that's what all code highlighters supposed to do.

        That won't work consistently though, as there is no way that I am aware of to set highlighter priority in QtCreator, so one is messing up another's highlights.

        aha_1980A D 2 Replies Last reply
        1
        • V Vladimir Looze

          I've found the "solution", there is a way to apply all previous formats in a block:

          for(QTextLayout::FormatRange &range : currentBlock().layout()->formats()) {
            setFormat(range.start, range.length, range.format);
          }
          

          One would think, that's what all code highlighters supposed to do.

          That won't work consistently though, as there is no way that I am aware of to set highlighter priority in QtCreator, so one is messing up another's highlights.

          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi @Vladimir-Looze,

          I guess the best is to contact the QtCreator developers on the mailing list: https://lists.qt-project.org/listinfo/qt-creator

          You should get a definite answer there.

          Regards

          Qt has to stay free or it will die.

          1 Reply Last reply
          0
          • V Vladimir Looze

            I've found the "solution", there is a way to apply all previous formats in a block:

            for(QTextLayout::FormatRange &range : currentBlock().layout()->formats()) {
              setFormat(range.start, range.length, range.format);
            }
            

            One would think, that's what all code highlighters supposed to do.

            That won't work consistently though, as there is no way that I am aware of to set highlighter priority in QtCreator, so one is messing up another's highlights.

            D Offline
            D Offline
            DavidSchulz
            wrote on last edited by
            #5

            @Vladimir-Looze
            I have never experimented with two different highlighters working on the same document, and as you have already encountered various problems I guess it was never the intention that this works.

            But if you want to have multiline suggestion I would like to encourage you to have a look at the copilot integration, and how the suggestions are handled there.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved