diff --git a/alire.toml b/alire.toml index f0a5b3d..a22a69f 100644 --- a/alire.toml +++ b/alire.toml @@ -1,5 +1,8 @@ name = "simple_logging" -version = "2.0.1-dev" +version = "3.0.0-dev" +# Breaking changes: +# 3.0: new completion text in Activity constructor + description = "Simple logging to console" licenses = "LGPL-3.0-only" website = "https://github.com/alire-project/simple_logging" diff --git a/src/simple_logging.adb b/src/simple_logging.adb index 2881844..fa39466 100644 --- a/src/simple_logging.adb +++ b/src/simple_logging.adb @@ -152,13 +152,17 @@ package body Simple_Logging is -- Activity -- -------------- - function Activity (Text : String; - Level : Levels := Info) return Ongoing is + function Activity (Text : String; + Autocomplete_Text : String := ""; + Level : Levels := Info) return Ongoing is begin - return This : Ongoing := (Ada.Finalization.Limited_Controlled with - Data => (Level => Level, - Start => Internal_Clock, - Text => To_Unbounded_String (Text))) + return This : Ongoing := + (Ada.Finalization.Limited_Controlled with + Data => (Level => Level, + Start => Internal_Clock, + Text => To_Unbounded_String (Text), + Text_Autocomplete => + To_Unbounded_String (Autocomplete_Text))) do Debug ("Status start: " & To_String (This.Data.Text)); Statuses.Insert (This.Data); @@ -216,11 +220,49 @@ package body Simple_Logging is procedure Finalize (This : in out Ongoing) is begin Debug ("Status ended: " & To_String (This.Data.Text)); - Clear_Status_Line; - Statuses.Difference (Status_Sets.To_Set (This.Data)); - This.Step; + if this.Data.Text_Autocomplete /= "" then + this.New_Line (To_String (This.Data.Text_Autocomplete)); + else + Clear_Status_Line; + Statuses.Difference (Status_Sets.To_Set (This.Data)); + This.Step; + end if; end Finalize; + -------------- + -- New_Line -- + -------------- + + procedure New_Line (This : in out Ongoing; + Text : String) + is + Old_Line : constant String := Build_Status_Line; + begin + -- Remove current status (unsure if this is needed) + Statuses.Exclude (This.Data); + + -- Print checkmark + Text and clear remainder of line + declare + Done_Line : constant String := + (if ASCII_Only + then "Done: " & Text + else U ("✔ ") & Text); + New_Len : constant Natural := Visible_Length (Done_Line); + Old_Len : constant Natural := Visible_Length (Old_Line); + begin + if Is_TTY and then New_Len > 0 then + GNAT.IO.Put_Line + (ASCII.CR + & Done_Line + & (1 .. Old_Len - Natural'Min (New_Len, Old_Len) => ' ')); + else + Clear_Status_Line (Old_Line); + GNAT.IO.Put_Line (""); + end if; + C.Flush_Stdout; + end; + end New_Line; + ---------- -- Step -- ---------- @@ -232,7 +274,7 @@ package body Simple_Logging is begin -- Update status if needed if New_Text /= "" or else Clear then - Statuses.Delete (This.Data); + Statuses.Exclude (This.Data); This.Data.Text := To_Unbounded_String (New_Text); Statuses.Insert (This.Data); end if; @@ -245,7 +287,7 @@ package body Simple_Logging is if Is_TTY and then New_Len > 0 then GNAT.IO.Put (ASCII.CR & New_Line - & (1 .. Old_Len - New_Len => ' ')); + & (1 .. Old_Len - Natural'Min (New_Len, Old_Len) => ' ')); C.Flush_Stdout; -- Advance the spinner diff --git a/src/simple_logging.ads b/src/simple_logging.ads index ff92660..1a02830 100644 --- a/src/simple_logging.ads +++ b/src/simple_logging.ads @@ -109,8 +109,16 @@ package Simple_Logging with Preelaborate is -- trailing '...' is added by this prompt. The rest of logging subprograms -- will emit normally over the status line. - function Activity (Text : String; - Level : Levels := Info) return Ongoing; + function Activity (Text : String; + Autocomplete_Text : String := ""; + Level : Levels := Info) return Ongoing; + -- Start an ongoing activity with given Text. If Autocomplete_Text is + -- provided, it will be used to complete the text when the activity ends. + -- When ASCII_Only is True, this results in "Done: " + -- being printed; otherwise, a checkmark-prefixed message is printed. + -- In both cases the status line is cleared. You can also use New_Line to + -- print a custom message and to jump to the next line, at end or + -- mid-progress. procedure Step (This : in out Ongoing; New_Text : String := ""; @@ -121,6 +129,10 @@ package Simple_Logging with Preelaborate is -- status contribution (e.g., because we are nesting further and this one -- becomes irrelevant) + procedure New_Line (This : in out Ongoing; + Text : String); + -- Remove the step text and print checkmark + Text and jump to next line. + ------------- -- Unicode -- ------------- @@ -139,9 +151,10 @@ private use Ada.Strings.Unbounded; type Ongoing_Data is record - Start : Duration; - Level : Levels; - Text : Unbounded_String; + Start : Duration; + Level : Levels; + Text : Unbounded_String; + Text_Autocomplete : Unbounded_String; end record; -- Non-limited data to be stored in collections @@ -152,7 +165,9 @@ private function "<" (L, R : Ongoing_Data) return Boolean is (L.Start < R.Start or else (L.Start = R.Start and then L.Level < R.Level) or else - (L.Start = R.Start and then L.Level = R.Level and then L.Text < R.Text)); + (L.Start = R.Start and then L.Level = R.Level and then L.Text < R.Text) or else + (L.Start = R.Start and then L.Level = R.Level and then L.Text = R.Text + and then L.Text_Autocomplete < R.Text_Autocomplete)); overriding procedure Finalize (This : in out Ongoing);