📄 syneditmiscprocs.pas
字号:
TabMask := TabWidth - 1;
repeat
if (pSrc^ = #9) then begin
i := TabWidth - (DestLen and TabMask);
Inc(DestLen, i);
//This is used for both drawing and other stuff and is meant to be #9 and not #32
repeat
pDest^ := #9;
Inc(pDest);
Dec(i);
until (i = 0);
Dec(TabCount);
if (TabCount = 0) then begin
repeat
Inc(pSrc);
pDest^ := pSrc^;
Inc(pDest);
until (pSrc^ = #0);
exit;
end;
end else begin
pDest^ := pSrc^;
Inc(pDest);
Inc(DestLen);
end;
Inc(pSrc);
until (pSrc^ = #0);
end else
HasTabs := FALSE;
end;
function ConvertTabs2n(const Line: AnsiString; TabWidth: integer): AnsiString;
var
HasTabs: boolean;
begin
Result := ConvertTabs2nEx(Line, TabWidth, HasTabs);
end;
function ConvertTabsEx(const Line: AnsiString; TabWidth: integer;
var HasTabs: boolean): AnsiString;
var
i, DestLen, TabCount: integer;
pSrc, pDest: PChar;
begin
Result := Line; // increment reference count only
if GetHasTabs(pointer(Line), DestLen) then begin
HasTabs := TRUE;
pSrc := @Line[1 + DestLen];
// We have at least one tab in the string, and the tab width is greater
// than 1. pSrc points to the first tab char in Line. We get the number
// of tabs and the length of the expanded string now.
TabCount := 0;
repeat
if (pSrc^ = #9) then begin
DestLen := DestLen + TabWidth - DestLen mod TabWidth;
Inc(TabCount);
end else
Inc(DestLen);
Inc(pSrc);
until (pSrc^ = #0);
// Set the length of the expanded string.
SetLength(Result, DestLen);
DestLen := 0;
pSrc := PChar(Line);
pDest := PChar(Result);
repeat
if (pSrc^ = #9) then begin
i := TabWidth - (DestLen mod TabWidth);
Inc(DestLen, i);
repeat
pDest^ := #9;
Inc(pDest);
Dec(i);
until (i = 0);
Dec(TabCount);
if (TabCount = 0) then begin
repeat
Inc(pSrc);
pDest^ := pSrc^;
Inc(pDest);
until (pSrc^ = #0);
exit;
end;
end else begin
pDest^ := pSrc^;
Inc(pDest);
Inc(DestLen);
end;
Inc(pSrc);
until (pSrc^ = #0);
end else
HasTabs := FALSE;
end;
function ConvertTabs(const Line: AnsiString; TabWidth: integer): AnsiString;
var
HasTabs: boolean;
begin
Result := ConvertTabsEx(Line, TabWidth, HasTabs);
end;
function IsPowerOfTwo(TabWidth: integer): boolean;
var
nW: integer;
begin
nW := 2;
repeat
if (nW >= TabWidth) then break;
Inc(nW, nW);
until (nW >= $10000); // we don't want 64 kByte spaces...
Result := (nW = TabWidth);
end;
function GetBestConvertTabsProc(TabWidth: integer): TConvertTabsProc;
begin
if (TabWidth < 2) then Result := TConvertTabsProc(@ConvertTabs1)
else if IsPowerOfTwo(TabWidth) then
Result := TConvertTabsProc(@ConvertTabs2n)
else
Result := TConvertTabsProc(@ConvertTabs);
end;
function GetBestConvertTabsProcEx(TabWidth: integer): TConvertTabsProcEx;
begin
if (TabWidth < 2) then Result := TConvertTabsProcEx(@ConvertTabs1Ex)
else if IsPowerOfTwo(TabWidth) then
Result := TConvertTabsProcEx(@ConvertTabs2nEx)
else
Result := TConvertTabsProcEx(@ConvertTabsEx);
end;
function GetExpandedLength(const aStr: string; aTabWidth: integer): integer;
var
iRun: PChar;
begin
Result := 0;
iRun := PChar(aStr);
while iRun^ <> #0 do
begin
if iRun^ = #9 then
Inc( Result, aTabWidth - (Result mod aTabWidth) )
else
Inc( Result );
Inc( iRun );
end;
end;
{***}
function CharIndex2CaretPos(Index, TabWidth: integer;
const Line: string): integer;
var
iChar: integer;
pNext: PChar;
begin
// possible sanity check here: Index := Max(Index, Length(Line));
if Index > 1 then begin
if (TabWidth <= 1) or not GetHasTabs(pointer(Line), iChar) then
Result := Index
else begin
if iChar + 1 >= Index then
Result := Index
else begin
// iChar is number of chars before first #9
Result := iChar;
// Index is *not* zero-based
Inc(iChar);
Dec(Index, iChar);
pNext := @Line[iChar];
while Index > 0 do begin
case pNext^ of
#0:
begin
Inc(Result, Index);
break;
end;
#9:
begin
// Result is still zero-based
Inc(Result, TabWidth);
Dec(Result, Result mod TabWidth);
end;
else Inc(Result);
end;
Dec(Index);
Inc(pNext);
end;
// done with zero-based computation
Inc(Result);
end;
end;
end else
Result := 1;
end;
function CaretPos2CharIndex(Position, TabWidth: integer; const Line: string;
var InsideTabChar: boolean): integer;
var
iPos: integer;
pNext: PChar;
begin
InsideTabChar := FALSE;
if Position > 1 then begin
if (TabWidth <= 1) or not GetHasTabs(pointer(Line), iPos) then
Result := Position
else begin
if iPos + 1 >= Position then
Result := Position
else begin
// iPos is number of chars before first #9
Result := iPos + 1;
pNext := @Line[Result];
// for easier computation go zero-based (mod-operation)
Dec(Position);
while iPos < Position do begin
case pNext^ of
#0: break;
#9: begin
Inc(iPos, TabWidth);
Dec(iPos, iPos mod TabWidth);
if iPos > Position then begin
InsideTabChar := TRUE;
break;
end;
end;
else Inc(iPos);
end;
Inc(Result);
Inc(pNext);
end;
end;
end;
end else
Result := Position;
end;
function StrScanForCharInSet(const Line: string; Start: integer;
AChars: TSynIdentChars): integer;
var
p: PChar;
begin
if (Start > 0) and (Start <= Length(Line)) then
begin
{$IFDEF SYN_MBCSSUPPORT}
// don't start on a trail byte
if ByteType(Line, Start) = mbTrailByte then
begin
Inc(Start);
if Start > Length(Line) then
begin
Result := 0;
Exit;
end;
end;
{$ENDIF}
p := PChar(@Line[Start]);
repeat
{$IFDEF SYN_MBCSSUPPORT}
// skip over multibyte characters
if p^ in LeadBytes then
begin
Inc(p);
Inc(Start);
if p^ = #0 then
Break;
end
else
{$ENDIF}
if p^ in AChars then
begin
Result := Start;
exit;
end;
Inc(p);
Inc(Start);
until p^ = #0;
end;
Result := 0;
end;
function StrRScanForCharInSet(const Line: string; Start: integer;
AChars: TSynIdentChars): integer;
var
I: Integer;
begin
Result := 0;
if (Start > 0) and (Start <= Length(Line)) then begin
{$IFDEF SYN_MBCSSUPPORT}
if not SysLocale.FarEast then begin
{$ENDIF}
for I := Start downto 1 do
if Line[I] in AChars then begin
Result := I;
Exit;
end;
{$IFDEF SYN_MBCSSUPPORT}
end
else begin
// it's a lot faster to start from the beginning and go forward than to go
// backward and call ByteType on every character
I := 1;
while I <= Start do begin
if Line[I] in LeadBytes then
Inc(I)
else if Line[I] in AChars then
Result := I;
Inc(I);
end;
end;
{$ENDIF}
end;
end;
{$IFDEF SYN_MBCSSUPPORT}
function StrScanForMultiByteChar(const Line: string; Start: Integer): Integer;
var
I: Integer;
begin
if SysLocale.FarEast and (Start > 0) and (Start <= Length(Line)) then begin
// don't start on a trail byte
if ByteType(Line, Start) = mbTrailByte then
Inc(Start);
for I := Start to Length(Line) do
if Line[I] in LeadBytes then begin
Result := I;
Exit;
end;
end;
Result := 0;
end;
{$ENDIF}
{$IFDEF SYN_MBCSSUPPORT}
function StrRScanForMultiByteChar(const Line: string; Start: Integer): Integer;
var
I: Integer;
begin
Result := 0;
if SysLocale.FarEast and (Start > 0) and (Start <= Length(Line)) then begin
// it's a lot faster to start from the beginning and go forward than to go
// backward and call ByteType on every character
I := 1;
while I <= Start do begin
if Line[I] in LeadBytes then begin
Result := I;
Inc(I);
end;
Inc(I);
end;
end;
end;
{$ENDIF}
function GetEOL(Line: PChar): PChar;
begin
Result := Line;
if Assigned(Result) then
while not (Result^ in [#0, #10, #13]) do
Inc(Result);
end;
{$IFOPT R+}{$DEFINE RestoreRangeChecking}{$ELSE}{$UNDEF RestoreRangeChecking}{$ENDIF}
{$R-}
function EncodeString(s: string): string;
var
i, j: integer;
begin
SetLength(Result, 2 * Length(s)); // worst case
j := 0;
for i := 1 to Length(s) do begin
Inc(j);
if s[i] = '\' then begin
Result[j] := '\';
Result[j + 1] := '\';
Inc(j);
end else if s[i] = '/' then begin
Result[j] := '\';
Result[j + 1] := '.';
Inc(j);
end else
Result[j] := s[i];
end; //for
SetLength(Result, j);
end; { EncodeString }
function DecodeString(s: string): string;
var
i, j: integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -