AshlinHarris / Spinners.jl

Command line spinners in Julia with Unicode support
MIT License
13 stars 1 forks source link

Spinner function and macros for the end user #58

Closed curio-sitas closed 1 year ago

curio-sitas commented 1 year ago

May close #14, #11 and #22 when the PR will be more advanced.

AshlinHarris commented 1 year ago

Thanks! I've made some big changes in the meantime, so I don't mind helping out with the merge, if needed.

curio-sitas commented 1 year ago

Thanks! I've made some big changes in the meantime, so I don't mind helping out with the merge, if needed.

No problem, i'll resolve the code conflicts to upgrade my changes based on yours.

curio-sitas commented 1 year ago

@AshlinHarris How are you using julia 1.9, did you just build the master dev branch ?

AshlinHarris commented 1 year ago

@curio-sitas No, I downloaded a nightly binary: https://julialang.org/downloads/nightlies/

AshlinHarris commented 1 year ago

61 fixes the integration tests.

curio-sitas commented 1 year ago

Well, i got all working but only in the spinner function scope. I'm wondering if it is possible to evaluate an expression in the function but in the global scope ...

like @spinner :clock2 x = 2 make the spinner spins but x does not exists

AshlinHarris commented 1 year ago

Well, i got all working but only in the spinner function scope. I'm wondering if it is possible to evaluate an expression in the function but in the global scope ...

like @spinner :clock2 x = 2 make the spinner spins but x does not exists

For me, this is the most important functionality, so I've sacrificed a lot of simplicity and readability for it. I want to keep a @spinner macro that can be added to a line of code and requires no other change.

One compromise might be to only accept bare function calls as input. That way, the user must take care of any scoping in their own code. But I want to avoid this sort of change.

curio-sitas commented 1 year ago

Well, i got all working but only in the spinner function scope. I'm wondering if it is possible to evaluate an expression in the function but in the global scope ... like @spinner :clock2 x = 2 make the spinner spins but x does not exists

For me, this is the most important functionality, so I've sacrificed a lot of simplicity and readability for it. I want to keep a @spinner macro that can be added to a line of code and requires no other change.

One compromise might be to only accept bare function calls as input. That way, the user must take care of any scoping in their own code. But I want to avoid this sort of change.

I agree, this is absolutely a needed property ! I think there is no way to create a simple macro that just calls only one backend function as only the macro can give you the scope for an expresssion evaluation. For function calling it might be easier but i will end with the idea of a macro doing both by calling a generic function. One way to overcome that is to recreate an independent macro with less customisation and then a function with more settings but with a local scope ?

AshlinHarris commented 1 year ago

I think we can keep your spinner function with all its features, and @spinner can have multiple definitions that each rely on it. There ought to be macro definitions that work in the current scope and for any number or type of arguments, but I'm not sure what the simplest way to define them is. I'll read more about metaprogramming and test some things out over the weekend.

AshlinHarris commented 1 year ago

@curio-sitas Huge breakthrough! I finally figured out how to define the macro:

macro spinner(inputs...)
    quote
        generate_spinner($(inputs[1:end-1]...))
        $(esc(inputs[end]))
    end
end

function generate_spinner(x...)
    println(x)
end

I'll keep testing it, but it looks like this @spinner always detects the user's command at the end, no matter its form (x = 4, f(x). begin ... end, etc.). Any other arguments are passed to generate_spinner, even if the list is empty.

curio-sitas commented 1 year ago

I think this is pretty all the PR wanted to achieve, i just need to rewrite the documentation quotes, and write the argument check and warnings for sanity.

The tests are passing on Windows only, i dont know why.

AshlinHarris commented 1 year ago

Outstanding work, @curio-sitas!

I'll accept the PR then rewrite the tests. The problem seems to be with due to putting IO redirection inside a let...end block.

I'll also make some minor additions. Currently, there is no timer_spin definition for empty inputs.