Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 09/20/24 in all areas

  1. havrlisan

    When LSP fails

    In this post, I'll share all the workarounds I use when LSP fails, which have greatly helped me during coding. Hopefully, you'll find them useful before Embarcadero completely fixes the LSP Server, which I'm sure will be soon. I'll also mention GExperts throughout this post, as it includes some useful features that can speed up using the tools listed below. Delphi Uses Helper Link: https://delphisorcery.blogspot.com/2021/03/introducing-delphi-uses-helper.html Feature: proper replacement for the Find Unit... refactor (Ctrl+Shift+A) feature. Description This has been by far the most helpful plugin. It's as simple as typing the name of a type and pressing Ctrl+Shift+A to find the unit where it's declared. When the window pops up, you can press Enter to add the unit to the uses section (use the left/right arrows to switch between interface and implementation sections), or press Shift+Enter to open the unit and jump to the line where the type is declared. GExperts bonus: The IDE already has a similar feature under the Refactor menu with the same shortcut, Ctrl+Shift+A, but it doesn’t work well and is certainly not as fast as Delphi Uses Helper. However, sometimes the default feature will trigger instead of the plugin (e.g., when pressing the shortcut without any text at the caret position). To remove the default shortcut, use GExperts' IDE Menu Shortcuts: find the shortcut under Refactor > Find Unit... (it should be the last one), and assign it to another key. MMX - Show Related Classes Link: https://www.mmx-delphi.de/ Feature: shows ancestor class, implemented interfaces, and sibling classes for a given class. Description Want to quickly navigate to a class’s ancestor or interface, or find out which siblings it has? This feature gives you exactly that, neatly and efficiently. To use it, right-click and go to MMX Commands > Navigate and Move > Show Related Classes. Or even better, map a shortcut by going to MMX > Properties > Key Bindings and finding Show Related Classes. I’ve personally mapped it to Shift+Alt+3. MMX - Open Unit... Link: https://www.mmx-delphi.de/ Feature: displays searchable units based on set configuration. Description Quickly displays all units based on your configuration. The configuration allows for adding units from the currently opened project or project group, and the following paths: Project Search path, IDE Library path, and IDE Browsing path. Find Original Symbol Feature: additional help navigating to a unit, type, or method. Description Using Find Declaration (Ctrl+Click) is known to fail occasionally, especially on bigger projects. What I've found helpful at times is to try using the Find Original Symbol that's located under the Search > Find Symbols menu item. I've personally mapped the Find Declaration to Ctrl+< and the Find Original Symbol to Ctrl+Shift+< through the GExperts IDE Menu Shortcuts, and I spam them when needed. It does help sometimes. Add a shortcut to the Reload LSP Server menu item Link: https://github.com/havrlisan/zx-idetools/blob/main/Source/Zx.IT.KeyBinding.ReloadLSPServer.pas Description In Delphi 12.1, a menu item Reload LSP Server was added under the Tools menu. Before that, you could add a custom tool to manually kill the LSP, and the IDE would restart it automatically. Unfortunately, they didn't add a shortcut for the menu item, so your options are limited to mouse clicks or to clicking Alt > T > accelerated key. Note that the accelerated key will be automatically assigned, and it depends on your menu items under the Tools menu, which sucks because that's the most changeable menu (because of custom tools, or third-party plugins). Usually, I'd use GExperts IDE Menu Shortcuts to manually add the shortcut, but the Reload LSP Server menu item doesn't show up there. After some debugging, I realized that the menu item in question isn't registered on IDE startup, but is loaded sometime after all other packages are loaded. My best guess is that the GExperts remembers the menu items when loaded, and doesn't re-fetch them afterward (I'm too lazy to search through the source code, sorry). So I decided to implement an IDE notifier that listens to a "ProjectGroupOpen" notification and then tries to find the Reload LSP Server menu item and assigns the shortcut to it. I've set the default shortcut to Alt+Shift+W, but the code is quite simple and is easily portable to a package of your own. That's all I've got so far. If you have some other features or tips, feel free to share them in this post!
  2. I just posted another update for SVGIconViewer. This version increases the icon count to over 46,500 with the addition of the Bootstrap icon library, the ability to view a user specified folder containing .svg files and export those files as a Delphi TImageCollection with generated png versions of the files with a single click. https://github.com/skamradt/SVGIconViewer
  3. Hi I has to be dome manually. "Find a file named sdkmanager.bat. Open a cmd prompt in this folder and enter these commands: sdkmanager "platform-tools" "platforms;android-33" sdkmanager "platform-tools" "platforms;android-34" " https://stackoverflow.com/questions/78292730/delphi-12-1-post-installation-configuration ZV
  4. I found myself down the rabbit hole of IEEE 754 standard on Floating-Point numbers (which Delphi follows), specifically the different values of NaN.... There are multiple potential internal values for NaN, all which evaluate as fsNaN. I found what I believe to be a bug, but I'm curious if anyone else has any thoughts on it. (As I was writing this up I discovered the behavior is only on Win32, so I've decided it must be a bug (RSS-1831), but sharing here anyway because I find the details interesting.) In short: IEEE 754 distinguishes between Signaling NaN and Quiet NaN. Delphi defaults to Quiet NaN, but you can make it signaling manually. Unfortunately, when a float is returned from a function in the Win32 compiler, the quiet flag is set. I was testing to see if Delphi converted it into an exception, which would be understandable, but instead it just silently sets the quiet flag, suppressing the signaling state. Testing in FPC, Delphi Win64, or Delphi Linux64, and the flag value doesn't change, which is what I would expect. Detailed explanation and background IEEE 754 divides a float into 3 parts Sign Exponent Fraction For a NaN the Exponent bits are all set ($FF in Single), any value for sign (Delphi's default NaN has it set, making it a negative NaN, which doesn't carry any specific significance), and the Fraction is anything but all 0. This allows for quiet a few different values that all are treated as NaN. What may distinguish the different values of NaN is signaling vs. quiet NaN. The Quiet flag is usually the first bit of the fraction. When the quiet flag isn't set, then it is considered a signaling NaN. The internal the internal representation of a NaN is typically displayed as follows (notice this is reversed from how Delphi stores the value in memory to put the most significant bit first.) S Exponent Fraction 1 | 11111111 | 10000000000000000000000 ^ The quiet flag So a signaling NaN is has an value for Faction without that first bit set. What I found in Delphi Win32 is it handles all these values correctly, except that if the quiet flag is missing (making it a signaling NaN), then when the value is returned from a function the quiet flag is set. Before returning from function: (Notice that the debugger recognizes it as negative NaN. Very nice!) This is 1 | 11111111 | 00000000000000000000001 in binary, which doesn't have the Quiet flag set 1 | 11111111 | 10000000000000000000001 After return it isn't the Default NaN, but it is the previous value with the Quiet flag set. Here is some sample code that demonstrates the behavior // The Delphi Win32 (tested in Delphi 12.1 and 12.2) sets NaN's quiet flag when are returning from a function // More information on IEEE 754 NaN https://en.wikipedia.org/wiki/NaN#Quiet_NaN // More information on this code: https://gist.github.com/jimmckeeth/2b4f017917afbae88ee7a3deb75b4ef7 program NaNSignalBug; {$APPTYPE CONSOLE} uses System.SysUtils;//, SingleUtils in 'SingleUtils.pas'; function is_Signaling(const NaN: Single): Boolean; begin Result := NaN.IsNan and (NaN.Frac and $400000 = 0); end; function NaNDetails(const Value: Single): string; begin if value.IsNan then begin if is_Signaling(value) then Result := 'NaN is Signaling' else Result := 'NaN is Quiet'; end else Result := 'Not a NaN'; end; procedure MakeSignaling(var NaN: Single); begin NaN.Exp := 255; NaN.Frac := NaN.Frac and not (1 shl 22); Assert(is_Signaling(NaN)); Writeln('Manipulated: ',NaNDetails(NaN),#9, '// Line 33'); end; // When a NaN is returned from a function the Signal bit is set function SignalingNaN: Single; begin Result := Single.NaN; Result.Frac := 1; MakeSignaling(Result); Assert(is_Signaling(Result)); Writeln(#9,'SignalingNaN Returning',#9'// Line 43'); end; function NestedNaN: Single; begin var NaN : Single := SignalingNaN; // The quiet bit was set Writeln('Returned: ',NaNDetails(NaN),#9, '// Line 50'); // without returning it from a function it works fine MakeSignaling(NaN); Writeln('Manipulated: ',NaNDetails(NaN),#9, '// Line 53'); Assert(is_Signaling(NaN)); Writeln(#9,'NestedNaN Returning ',#9,'// Line 55'); Exit(NaN); end; begin try Writeln(TOSVersion.ToString); Writeln('Used: ',SizeOf(NativeInt)*8,'-bit compiler'); var NaN : Single := NestedNaN; // The quiet bit was set Writeln('Returned: ', NaNDetails(NaN),#9,'// Line 66'); //Assert(is_Signaling(NaN)); // Fails on Win32 // without returning it from a function it works fine MakeSignaling(NaN); Writeln('Manipulated: ', NaNDetails(NaN),#9,'// Line 70'); Assert(is_Signaling(NaN)); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; readln; end. and here is the output Windows 11 (Version 23H2, OS Build 22631.4169, 64-bit Edition) Used: 32-bit compiler Manipulated: NaN is Signaling // Line 33 SignalingNaN Returning // Line 43 Returned: NaN is Quiet // Line 50 Manipulated: NaN is Signaling // Line 33 Manipulated: NaN is Signaling // Line 53 NestedNaN Returning // Line 55 Returned: NaN is Quiet // Line 66 Manipulated: NaN is Signaling // Line 33 Manipulated: NaN is Signaling // Line 70 and a more detailed look at the NaN values Default NaN Value of : Nan Special : fsNaN Sign : TRUE Exponent : 255 Fraction : 4194304 Size : 4 InvertHex: $FFC00000 1 | 11111111 | 10000000000000000000000 ----------------- Singnaling NaN Value of : Nan Special : fsNaN Sign : TRUE Exponent : 255 Fraction : 1 Size : 4 InvertHex: $FF800001 1 | 11111111 | 00000000000000000000001 ----------------- Returned from Function Value of : Nan Special : fsNaN Sign : TRUE Exponent : 255 Fraction : 4194305 Size : 4 InvertHex: $FFC00001 1 | 11111111 | 10000000000000000000001 @David Heffernan it was suggested I tag you on this... NaNSignalBug.dpr
  5. If you are using the type library editor to create your RIDL - delphi should be mapping those methods as safecall. Check your options Edit : the default is only dual interfaces - this is something I change when ever I install a new version of delphi.
  6. vfbb

    White screen on iPhoneX

    Seems related to “Display zoom” option of iOS. Issue reported here: https://github.com/skia4delphi/skia4delphi/issues/315
  7. If you want, you can try this. Is the same COM but with new application: you don't need to register the COM Try to unregsiter the old one. After that build the projetc group (it is setting for WIn64 but you can change for WIn32) and run ... all is working without register the COM thanks to SxS technology (SideBySide). The EXE and DLL will be put in Bin32 and Bin64 (and there are already the manifests). There is a ReadMe and some Manifests (they are all equal excpet for the manifest that is included in the Project1 options). Bye Demo COM SxS.zip
  8. aehimself

    Parsing a json file

    I had to fire up my dev machine so I did a small test for you. The following code can be simplified a lot but at least it's easy to see what's going on: procedure TForm1.Button1Click(Sender: TObject); Var fulljson, group1, items: TJSONObject; enumpair: TJSONPair; begin fulljson := TJSONObject(TJSONObject.ParseJSONValue(Memo1.Lines.Text)); If Not Assigned(fulljson) Then Exit; Memo2.Lines.Add('JSON parsed successfully.'); group1 := TJSONObject(fulljson.GetValue('Group1')); If Not Assigned(group1) Then Exit; Memo2.Lines.Add('Group1 found!'); For enumpair In group1 Do Begin Memo2.Lines.Add('Found ' + enumpair.JsonString.Value + ' under Group1'); items := TJSONObject(enumpair.JsonValue); Memo2.Lines.Add('ImgHot: ' + items.GetValue<String>('ImgHot')); Memo2.Lines.Add('ImgNormal: ' + items.GetValue<String>('ImgNormal')); Memo2.Lines.Add('ImgChannel: ' + items.GetValue<String>('ImgChannel')); Memo2.Lines.Add('Caption: ' + items.GetValue<String>('Caption')); End; It successfully walks through your JSON file:
  9. aehimself

    DelphiLSP.Exe version 11.1 vs 12.2

    The 64 bit DelphiLSP simply hangs on my mid-sized project, just spins the progress bar over and over again, still saying 0% is done. 32 bit works fine on the same project, performance feels about the same as in 12.1. This is from the 12.2 document, fyi work on most symbols, sometimes resolves 🙂 Unfortunately yes, LSP needs some work to be actually good. Ctrl-click often doesn't work, jiggly lines at wrong places, errors in editor but project compiles... It can be lived together with if you already got used to Delphi's quirks 🙂
  10. Uwe Raabe

    When will we have a 64-bit IDE version ?

    Nobody claimed it were a 64 bit IDE. Only the compilers and the LSP server are available as 64 bit versions. The IDE still is 32 bit. That is why the 64 bit compilers can only be used with the MSBuild option.
  11. msohn

    Universal macOS apps deploy

    You only need to make sure you compile a universal binary. Packing and deployment is unaffected. Ensure the ARM64 platform is enabled and the compiler option set as described here: https://docwiki.embarcadero.com/RADStudio/Athens/en/Delphi_Considerations_for_Multi-Device_Applications#Universal_Binaries
  12. Anders Melander

    When will we have a 64-bit IDE version ?

    It isn't. I haven't installed it, but I can read.
  13. Borni

    Delphi 12.2 TMEMO - indexoutofbounds

    in FMX.Platform.UI.Android.pas markieren Code: procedure TTextServiceAndroid.InternalUpdateSelection; var SelStart, SelEnd: Integer; begin if FTextView = nil then Exit; CalculateSelectionBounds(SelStart, SelEnd); if SelEnd - SelStart > 0 then FTextView.setSelection(SelStart, SelEnd) else FTextView.setSelection(JCharSequenceToStr(FTextView.getText).length); // the chagnes found by Enri end;
×