88#include < cstdlib>
99#include < iostream>
1010#include < map>
11+ #include < optional>
1112#include < string>
1213
1314#include < fmt/color.h>
2324#include " mamba/core/tasksync.hpp"
2425#include " mamba/core/thread_utils.hpp"
2526#include " mamba/core/util.hpp"
27+ #include " mamba/core/util_os.hpp"
2628#include " mamba/specs/conda_url.hpp"
2729#include " mamba/util/string.hpp"
2830#include " mamba/util/synchronized_value.hpp"
@@ -301,6 +303,7 @@ namespace mamba
301303 {
302304 std::unique_ptr<ProgressBarManager> progress_bar_manager;
303305 ConsoleBuffer buffer;
306+ std::optional<std::size_t > active_in_place_width;
304307 };
305308
306309 util::synchronized_value<Data> m_synched_data;
@@ -346,7 +349,8 @@ namespace mamba
346349
347350 bool Console::can_report_status ()
348351 {
349- return is_available () && !instance ().context ().output_params .json ;
352+ const auto & ctx = instance ().context ();
353+ return is_available () && ctx.command_params .is_mamba_exe && !ctx.output_params .json ;
350354 }
351355
352356 void Console::cancel_json_print ()
@@ -371,11 +375,54 @@ namespace mamba
371375 }
372376 else
373377 {
378+ if (synched_data->active_in_place_width .has_value ())
379+ {
380+ std::cout << ' \n ' ;
381+ synched_data->active_in_place_width .reset ();
382+ }
374383 std::cout << hide_secrets (str) << std::endl;
375384 }
376385 }
377386 }
378387
388+ void Console::print_in_place (std::string_view str, bool finalize, bool force_print)
389+ {
390+ if (force_print || !(context ().output_params .quiet || context ().output_params .json ))
391+ {
392+ auto synched_data = p_data->m_synched_data .synchronize ();
393+
394+ if (synched_data->progress_bar_manager && synched_data->progress_bar_manager ->started ())
395+ {
396+ synched_data->buffer .push_back (hide_secrets (str));
397+ return ;
398+ }
399+
400+ const std::string sanitized = hide_secrets (str);
401+ const bool can_update_in_place = is_atty (std::cout);
402+ if (!can_update_in_place)
403+ {
404+ std::cout << sanitized << std::endl;
405+ return ;
406+ }
407+
408+ const std::size_t previous_width = synched_data->active_in_place_width .value_or (0 );
409+ const std::size_t next_width = sanitized.size ();
410+ const std::size_t pad = previous_width > next_width ? previous_width - next_width : 0 ;
411+ std::cout << ' \r ' << sanitized << std::string (pad, ' ' );
412+
413+ if (finalize)
414+ {
415+ std::cout << ' \n ' ;
416+ synched_data->active_in_place_width .reset ();
417+ }
418+ else
419+ {
420+ std::cout << std::flush;
421+ synched_data->active_in_place_width = next_width;
422+ }
423+ }
424+ }
425+
379426 void Console::print_buffer (std::ostream& ostream)
380427 {
381428 auto & data = instance ().p_data ;
0 commit comments