anchor.diff:     end;
   end;
   
  -procedure TEditorFrame.DoSaveHistory_Bookmarks(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString);
  +procedure TEditorFrame.DoLoadHistory_Bookmarks(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString);
   var
     items, items2: TStringList;
  -  bookmark: PATBookmarkItem;
  -  i: integer;
  -begin
  +  BmData: TATBookmarkData;
  +  nTop, nKind, i: integer;
  +begin
  +  FillChar(BmData, SizeOf(BmData), 0);
  +  BmData.ShowInBookmarkList:= true;
  +
     items:= TStringList.Create;
     items2:= TStringList.Create;
  -  try
  -    for i:= 0 to Ed.Strings.Bookmarks.Count-1 do
  -    begin
  -      bookmark:= Ed.Strings.Bookmarks[i];
  -      //save usual bookmarks and numbered bookmarks (kind=1..10)
  -      if (bookmark^.Data.Kind>10) then Continue;
  -      items.Add(IntToStr(bookmark^.Data.LineNum));
  -      items2.Add(IntToStr(bookmark^.Data.Kind));
  -    end;
  -
  -    if items.Count>0 then
  -      c.SetValue(path+cHistory_Bookmark, items)
  -    else
  -      c.DeleteValue(path+cHistory_Bookmark);
  -
  -    if items2.Count>0 then
  -      c.SetValue(path+cHistory_BookmarkKind, items2)
  -    else
  -      c.DeleteValue(path+cHistory_BookmarkKind);
  -
  -  finally
  -    FreeAndNil(items2);
  -    FreeAndNil(items);
  -  end;
  -end;
  -
  -procedure TEditorFrame.DoSaveHistoryEx(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString);
  -begin
  -  //save 'split' value only when we have single file splitted,
  -  //but not 2 different files (like user.json + default.json)
  -  if FileName2='' then
  -  if UiOps.HistoryItems[ahhTabSplit] then
  -  begin
  -    if Splitted then
  -      c.SetValue(path+cHistory_TabSplit, Format('%s,%d', [
  -        BoolToStr(SplitHorz, '1', '0'),
  -        Round(SplitPos*cHistory_TabSplit_Mul)
  -        ]))
  -    else
  -      c.DeleteValue(path+cHistory_TabSplit);
  -  end;
  -
  -  if UiOps.HistoryItems[ahhLexer] then
  -    c.SetDeleteValue(path+cHistory_Lexer, LexerName[Ed], '');
  -
  -  if UiOps.HistoryItems[ahhEncoding] then
  -    c.SetValue(path+cHistory_Enc, Ed.EncodingName);
  -
  -  if UiOps.HistoryItems[ahhTopLine] then
  -  begin
  -    c.SetDeleteValue(path+cHistory_TopLine, Ed.LineTop, 0);
  -    if EditorsLinked and Splitted then
  -      c.SetDeleteValue(path+cHistory_TopLine2, Ed2.LineTop, 0);
  -  end;
  -
  -  if UiOps.HistoryItems[ahhWordWrap] then
  -    c.SetDeleteValue(path+cHistory_Wrap, Ord(Ed.OptWrapMode), Ord(EditorOps.OpWrapMode));
  -
  -  if not Ed.IsReadOnlyAutodetected then
  -    c.SetDeleteValue(path+cHistory_ReadOnly, ReadOnly[Ed], false);
  -
  -  if UiOps.HistoryItems[ahhRuler] then
  -    c.SetDeleteValue(path+cHistory_Ruler, Ord(Ed.OptRulerVisible), Ord(EditorOps.OpRulerShow));
  -
  -  if UiOps.HistoryItems[ahhMinimap] then
  -    c.SetDeleteValue(path+cHistory_Minimap, Ord(Ed.OptMinimapVisible), Ord(EditorOps.OpMinimapShow));
  -
  -  if UiOps.HistoryItems[ahhMicromap] then
  -    c.SetDeleteValue(path+cHistory_Micromap, Ord(Ed.OptMicromapVisible), Ord(EditorOps.OpMicromapShow));
  -
  -  if UiOps.HistoryItems[ahhTabSize] then
  -  begin
  -    c.SetValue(path+cHistory_TabSize, Ed.OptTabSize);
  -    c.SetValue(path+cHistory_TabSpace, Ed.OptTabSpaces);
  -  end;
  -
  -  if UiOps.HistoryItems[ahhUnprinted] then
  -  begin
  -    c.SetDeleteValue(path+cHistory_Unpri, Ord(Ed.OptUnprintedVisible), Ord(EditorOps.OpUnprintedShow));
  -    c.SetDeleteValue(path+cHistory_Unpri_Spaces, Ord(Ed.OptUnprintedSpaces),      Ord(Pos('s', EditorOps.OpUnprintedContent)>0));
  -    c.SetDeleteValue(path+cHistory_Unpri_Ends, Ord(Ed.OptUnprintedEnds),          Ord(Pos('e', EditorOps.OpUnprintedContent)>0));
  -    c.SetDeleteValue(path+cHistory_Unpri_Detail, Ord(Ed.OptUnprintedEndsDetails), Ord(Pos('d', EditorOps.OpUnprintedContent)>0));
  -  end;
  -
  -  if UiOps.HistoryItems[ahhLineNumbers] then
  -    c.SetDeleteValue(path+cHistory_LineNums, Ord(Ed.Gutter[Ed.GutterBandNumbers].Visible), 1);
  -
  -  if UiOps.HistoryItems[ahhScale] then
  -    c.SetDeleteValue(path+cHistory_FontScale, Ed.OptScaleFont, 0);
  -
  -  if UiOps.HistoryItems[ahhFolding] then
  -  begin
  -    c.SetDeleteValue(path+cHistory_FoldingShow, Ord(Ed.Gutter[Ed.GutterBandFolding].Visible), 1);
  -    c.SetDeleteValue(path+cHistory_FoldedRanges, Ed.FoldingAsString, '');
  -  end;
  -
  -  if UiOps.HistoryItems[ahhTabColor] then
  -  begin
  -    if TabColor=clNone then
  -      c.DeleteValue(path+cHistory_TabColor)
  -    else
  -      c.SetValue(path+cHistory_TabColor, ColorToString(TabColor));
  -  end;
  -
  -  if UiOps.HistoryItems[ahhCaret] then
  -    DoSaveHistory_Caret(Ed, c, path);
  -
  -  {
  -  //it's bad to save markers along with other history items,
  -  //because if a snippet (with markers) inserted + file was not saved after it,
  -  //we have wrong markers to save
  -  if UiOps.HistoryItems[ahhMarkers] then
  -    c.SetDeleteValue(path+cHistory_Markers, Ed.Markers.AsString, '');
  -  }
  -
  -  if UiOps.HistoryItems[ahhBookmarks] then
  -    DoSaveHistory_Bookmarks(Ed, c, path);
  -
  -  if UiOps.HistoryItems[ahhCodeTreeFilter] then
  -  begin
  -    c.SetDeleteValue(path+cHistory_CodeTreeFilter, FCodetreeFilter, '');
  -
  -    if FCodetreeFilterHistory.Count>0 then
  -      c.SetValue(path+cHistory_CodeTreeFilters, FCodetreeFilterHistory)
  -    else
  -      c.DeleteValue(path+cHistory_CodeTreeFilters);
  -  end;
  -end;
  -
  -procedure _WriteStringToFileInHiddenDir(const fn, s: string);
  -var
  -  dir: string;
  -begin
  -  if s<>'' then
  -  begin
  -    dir:= ExtractFileDir(fn);
  -    if not DirectoryExists(dir) then
  -    begin
  -      CreateDir(dir);
  -      {$ifdef windows}
  -      FileSetAttr(dir, faHidden);
  -      {$endif}
  -    end;
  -    DoWriteStringToFile(fn, s);
  -  end
  -  else
  -  begin
  -    if FileExists(fn) then
  -      DeleteFile(fn);
  -  end;
  -end;
  -
  -procedure TEditorFrame.DoSaveUndo(Ed: TATSynEdit; const AFileName: string);
  -begin
  -  if IsFilenameListedInExtensionList(AFileName, UiOps.UndoPersistent) then
  -  begin
  -    _WriteStringToFileInHiddenDir(GetAppUndoFilename(AFileName, false), Ed.UndoAsString);
  -    _WriteStringToFileInHiddenDir(GetAppUndoFilename(AFileName, true), Ed.RedoAsString);
  -  end;
  -end;
  -
  -procedure TEditorFrame.DoLoadHistory(Ed: TATSynEdit; AllowEnc: boolean);
  -var
  -  cfg: TJSONConfig;
  -  SFileName: string;
  -  path: string;
  -begin
  -  SFileName:= GetFileName(Ed);
  -  if SFileName='' then exit;
  -  path:= SMaskFilenameSlashes(SFileName);
  -
  -  if UiOps.MaxHistoryFiles<2 then exit;
  -
  -  cfg:= TJsonConfig.Create(nil);
  -  try
  -    try
  -      cfg.Formatted:= true;
  -      cfg.Filename:= AppFile_HistoryFiles;
  -    except
  -      MsgBadConfig(AppFile_HistoryFiles);
  -      exit
  -    end;
  -
  -    DoLoadHistoryEx(Ed, cfg, path, AllowEnc);
  -  finally
  -    cfg.Free;
  -  end;
  -end;
  -
  -
  -procedure TEditorFrame.DoLoadHistoryEx(Ed: TATSynEdit; c: TJsonConfig;
  -  const path: UnicodeString; AllowEnc: boolean);
  -var
  -  str, str0, sFileName, sCaretString: string;
  -  Caret: TATCaretItem;
  -  NCaretPosX, NCaretPosY,
  -  NCaretEndX, NCaretEndY: integer;
  -  nTop, nKind, i: integer;
  -  items, items2: TStringlist;
  -  BmData: TATBookmarkData;
  -  Sep: TATStringSeparator;
  -  NFlag: integer;
  -begin
  -  sFileName:= GetFileName(Ed);
  -
  -  FillChar(BmData, SizeOf(BmData), 0);
  -  BmData.ShowInBookmarkList:= true;
  -
  -  //file not listed in history file? exit
  -  sCaretString:= c.GetValue(path+cHistory_Caret, '');
  -  if sCaretString='' then exit;
  -
  -  {
  -  //markers
  -  //it's bad to save markers along with other history items,
  -  //so this is commented
  -  Ed.Markers.AsString:= c.GetValue(path+cHistory_Markers, '');
  -  }
  -
  -  //split state
  -  str:= c.GetValue(path+cHistory_TabSplit, '');
  -  if str<>'' then
  -  begin
  -    Sep.Init(str);
  -    Sep.GetItemInt(i, 0);
  -    SplitHorz:= i=1;
  -    Splitted:= true;
  -    Sep.GetItemInt(i, 0);
  -    if i>0 then
  -      SplitPos:= i/cHistory_TabSplit_Mul;
  -  end;
  -
  -  //lexer
  -  str0:= LexerName[Ed];
  -  str:= c.GetValue(path+cHistory_Lexer, ''); //missed value means none-lexer (for Cud 1.104 or older)
  -  if (str='') or (str<>str0) then //better call it for none-lexer to apply "keys lexer -.json"
  -    LexerName[Ed]:= str;
  -
  -  //encoding
  -  if AllowEnc then
  -  begin
  -    str0:= Ed.EncodingName;
  -    str:= c.GetValue(path+cHistory_Enc, str0);
  -    if str<>str0 then
  -    begin
  -      Ed.EncodingName:= str;
  -      //reread in encoding
  -      //but only if not modified (modified means other text is loaded)
  -      if sFileName<>'' then
  -        if not Ed.Modified then
  -        begin
  -          Ed.Strings.EncodingDetect:= false;
  -          Ed.LoadFromFile(sFileName);
  -          Ed.Strings.EncodingDetect:= true;
  -        end;
  -    end;
  -  end;
  -
  -  TabColor:= StringToColorDef(c.GetValue(path+cHistory_TabColor, ''), clNone);
  -
  -  if not Ed.IsReadOnlyAutodetected then
  -    ReadOnly[Ed]:= c.GetValue(path+cHistory_ReadOnly, ReadOnly[Ed]);
  -
  -  if not FileWasBig[Ed] then
  -  begin
  -    NFlag:= c.GetValue(path+cHistory_Wrap, -1);
  -    if NFlag>=0 then
  -      if Ed.OptWrapMode<>TATEditorWrapMode(NFlag) then
  -      begin
  -        Ed.OptWrapMode:= TATEditorWrapMode(NFlag);
  -        Ed.IsModifiedWrapMode:= true;
  -        //DoPyEventState(Ed, EDSTATE_WRAP); //is not needed for session loading
  -      end;
  -
  -    NFlag:= c.GetValue(path+cHistory_Minimap, -1);
  -    if NFlag>=0 then
  -    begin
  -      Ed.OptMinimapVisible:= NFlag=1;
  -      Ed.IsModifiedMinimapVisible:= true;
  -    end;
  -
  -    NFlag:= c.GetValue(path+cHistory_Micromap, -1);
  -    if NFlag>=0 then
  -    begin
  -      Ed.OptMicromapVisible:= NFlag=1;
  -      Ed.IsModifiedMicromapVisible:= true;
  -    end;
  -  end;
  -
  -  NFlag:= c.GetValue(path+cHistory_Ruler, -1);
  -  if NFlag>=0 then
  -  begin
  -    Ed.OptRulerVisible:= NFlag=1;
  -    Ed.IsModifiedRulerVisible:= true;
  -  end;
  -
  -  Ed.OptTabSize:= c.GetValue(path+cHistory_TabSize, Ed.OptTabSize);
  -  Ed.OptTabSpaces:= c.GetValue(path+cHistory_TabSpace, Ed.OptTabSpaces);
  -
  -  NFlag:= c.GetValue(path+cHistory_Unpri, -1);
  -  if NFlag>=0 then
  -  begin
  -    Ed.OptUnprintedVisible:= NFlag=1;
  -    Ed.IsModifiedUnprintedVisible:= true;
  -  end;
  -
  -  NFlag:= c.GetValue(path+cHistory_Unpri_Spaces, -1);
  -  if NFlag>=0 then
  -  begin
  -    Ed.OptUnprintedSpaces:= NFlag=1;
  -    Ed.IsModifiedUnprintedSpaces:= true;
  -  end;
  -
  -  NFlag:= c.GetValue(path+cHistory_Unpri_Ends, -1);
  -  if NFlag>=0 then
  -  begin
  -    Ed.OptUnprintedEnds:= NFlag=1;
  -    Ed.IsModifiedUnprintedEnds:= true;
  -  end;
  -
  -  NFlag:= c.GetValue(path+cHistory_Unpri_Detail, -1);
  -  if NFlag>=0 then
  -  begin
  -    Ed.OptUnprintedEndsDetails:= NFlag=1;
  -    Ed.IsModifiedUnprintedEndDetails:= true;
  -  end;
  -
  -  with Ed.Gutter[Ed.GutterBandNumbers] do
  -  begin
  -    NFlag:= c.GetValue(path+cHistory_LineNums, -1);
  -    if NFlag>=0 then
  -    begin
  -      Visible:= NFlag=1;
  -      Ed.IsModifiedGutterNumbersVisible:= true;
  -    end;
  -  end;
  -
  -  with Ed.Gutter[Ed.GutterBandFolding] do
  -  begin
  -    NFlag:= c.GetValue(path+cHistory_FoldingShow, -1);
  -    if NFlag>=0 then
  -    begin
  -      Visible:= NFlag=1;
  -      Ed.IsModifiedGutterFoldingVisible:= true;
  -    end;
  -  end;
  -
  -  Ed.OptScaleFont:= c.GetValue(path+cHistory_FontScale, 0);
  -
  -  if Assigned(Lexer[Ed]) then
  -    Ed.FoldingAsStringTodo:= c.GetValue(path+cHistory_FoldedRanges, '');
  -
  -  nTop:= c.GetValue(path+cHistory_TopLine, 0);
  -  if nTop>0 then
  -    Ed.LineTop:= nTop;
  -
  -  if EditorsLinked and Splitted then
  -  begin
  -    nTop:= c.GetValue(path+cHistory_TopLine2, 0);
  -    if nTop>0 then
  -      Ed2.LineTop:= nTop;
  -  end;
  -
  -  //caret
  -  Sep.Init(sCaretString);
  -  Sep.GetItemInt(NCaretPosX, 0);
  -  Sep.GetItemInt(NCaretPosY, 0);
  -  Sep.GetItemInt(NCaretEndX, -1);
  -  Sep.GetItemInt(NCaretEndY, -1);
  -
  -  if Ed.Carets.Count<>1 then
  -    Ed.DoCaretSingle(0, 0);
  -  Caret:= Ed.Carets[0];
  -  if Caret.Change(NCaretPosX, NCaretPosY, NCaretEndX, NCaretEndY) then
  -  begin
  -    Ed.DoCaretsFixIncorrectPos(true);
  -    Ed.DoEventCarets;
  -  end;
  -
  -  //solve CudaText #3288, so Undo jumps to initial caret pos
  -  Ed.Strings.ActionSaveLastEditionPos(NCaretPosX, NCaretPosY);
  -
  -  //bookmarks
  -  items:= TStringList.create;
  -  items2:= TStringList.create;
     try
       c.GetValue(path+cHistory_Bookmark, items, '');
       c.GetValue(path+cHistory_BookmarkKind, items2, '');
  
positive.code:     FreeAndNil(items2);
      FreeAndNil(items);
    end;
  
    FCodetreeFilter:= c.GetValue(path+cHistory_CodeTreeFilter, '');
    c.GetValue(path+cHistory_CodeTreeFilters, FCodetreeFilterHistory, '');
  
negative.code:     procedure DoSaveHistoryEx(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString);
      procedure DoLoadHistory(Ed: TATSynEdit; AllowEnc: boolean);
      procedure DoLoadHistoryEx(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString; AllowEnc: boolean);
      procedure DoLoadHistory_Bookmarks(Ed: TATSynEdit; c: TJsonConfig; const path: UnicodeString);
      //misc
      function DoPyEvent(AEd: TATSynEdit; AEvent: TAppPyEvent; const AParams: TAppVariantArray): TAppPyEventResult;
      procedure DoPyEventState(Ed: TATSynEdit; AState: integer);
  