delphiutf-8otapi

How to get the specific line string (UTF8) or specific line string length in source editor using OpenToolsAPI


I want to fetch the entire line string (UTF8) and want to do operation on the line string. I have tried following code. but if we are having multibyte characters am not able to do this.

J:=1;
  CurrentRowStr :='';
  while True do
  begin
    //detect end of line
    Buffer.EditPosition.Move(Changes[I].FLine,J);
    CurrentRowStr := CurrentRowStr + Buffer.EditPosition.Character ;
    J := J+1;
  end;
  CurrentRowStr := Buffer.EditPosition.Read(J-1);

if anyone can help me to get particular line string using OpenToolsAPI, it would be great help.


Solution

  • You can use a IOTAEditReader to get entire lines. The following code is from my Conversion Helper Package. Most of this revolves around the GetCurrentLineParams function:

    function GetEditor: IOTASourceEditor;
    var
      ModuleServices: IOTAModuleServices;
      Module: IOTAModule;
      I: Integer;
    begin
      ModuleServices := BorlandIDEServices as IOTAModuleServices;
      Module := ModuleServices.CurrentModule;
      for I := 0 to Module.GetModuleFileCount - 1 do
        if Supports(Module.GetModuleFileEditor(I), IOTASourceEditor, Result) then
          Break;
    end;
    
    function GetLineAtCharPos(const Editor: IOTASourceEditor;
      const EditView: IOTAEditView; CharPos: TOTACharPos): string;
    var
      EditReader: IOTAEditReader;
      Start, Len: Integer;
      Res: AnsiString;
    begin
      CharPos.CharIndex := 0;
      Start := EditView.CharPosToPos(CharPos);
      Inc(CharPos.Line);
      Len := EditView.CharPosToPos(CharPos) - Start;
      if Len > 0 then
      begin
        SetLength(Res, Len);
        EditReader := Editor.CreateReader;
        EditReader.GetText(Start, PAnsiChar(Res), Len);
        Result := string(PAnsiChar(Res));
      end;
    end;
    
    function GetCurrentLine(const Editor: IOTASourceEditor;
      var BufferStart, Index: LongInt): string;
    var
      BufferLength: LongInt;
      EditReader: IOTAEditReader;
      Res: AnsiString;
    begin
      GetCurrentLineParams(Editor, BufferStart, BufferLength, Index);
      SetLength(Res, BufferLength);
      EditReader := Editor.CreateReader;
      EditReader.GetText(BufferStart, PAnsiChar(Res), BufferLength);
      Result := string(PAnsiChar(Res)); // just to be sure.
    end;
    
    function GetCurrentCharPos(const Editor: IOTASourceEditor; out EditView:
      IOTAEditView): TOTACharPos;
    var
      CursorPos: TOTAEditPos;
    begin
      EditView := Editor.GetEditView(0);
      CursorPos := EditView.CursorPos;
      EditView.ConvertPos(True, CursorPos, Result);
    end;
    
    procedure GetCurrentLineParams(const Editor: IOTASourceEditor;
      var Start, Length, Index: Integer);
    var
      EditView: IOTAEditView;
      CharPos: TOTACharPos;
    begin
      CharPos := GetCurrentCharPos(Editor, EditView);
      Index := CharPos.CharIndex + 1;
      CharPos.CharIndex := 0;
      Start := EditView.CharPosToPos(CharPos);
      Inc(CharPos.Line);
      Length := EditView.CharPosToPos(CharPos) - Start;
    end;
    
    function GetCurrentLineStart(const Editor: IOTASourceEditor): Integer;
    var
      L, I: Integer;
    begin
      GetCurrentLineParams(Editor, Result, L, I);
    end;
    
    function GetCurrentLineLength(const Editor: IOTASourceEditor): Integer;
    var
      S, I: Integer;
    begin
      GetCurrentLineParams(Editor, S, Result, I);
    end;