
Script of the day: Have a Menu that displays all open tabs in DrRacket. (Currently, DrRacket displays only the first 10).
How to install: Click on Scripts | Manage scripts | New script… Enter “All tabs” (a new script opens filled with a template.
Replace the template with the code below. Save the file.
Click on Scripts | All tabs. A new menu “All tabs” appears in DrRacket!

Pls post to reddit

I don’t use reddit, but if you want to do it, be my guest :slightly_smiling_face:

Can you post to Racket users and I’ll link back

I’m actually digging a hole in the garden atm. I just worry because lots of good stuff shows up on slack and gets lost forever. RacketUsers>Reddit anyway


@robby I must be doing something wrong. I’m still trying to make a quickscript that does send the-drracket-frame open-in-new-tab some-file
, and it keeps failing with “something’s missing in the namespace.” The problem is that it only gives me one missing module at a time, and each time I have to restart DrRacket.
Up to now, I’ve added these modules: drracket/tool-lib racket/match/stxtime
syntax/parse/experimental/template
syntax/parse/lib/function-header
racket/contract/private/arr-util
syntax/name
racket/contract/base
racket/contract/private/opt-guts
racket/contract/private/arr-i-parse
racket/contract/private/top-sort
racket/contract/private/ds-helpers
syntax/free-vars
(submod racket/match/define-forms lazy-require-aux-1-0)
and it keeps asking for more. I can easily imagine it’s going to ask for a hundred or more, which would take me hours…
What am I missing?

Is that method being called on the main thread of the DrRacket event space?

I have a namespace anchor in the tool.rkt file that defines the DrRacket plugin

In general I think DrRackets api stuff depends on being in a fairly reasonable context (parameter settings etc) and I guess that the way you set up namespaces could be breaking those assumptions.

Then I create a namespace with: (define (make-script-namespace)
(define ns (make-base-empty-namespace))
(for ([mod '(racket/class racket/gui/base
<many other requires>
(namespace-attach-module (namespace-anchor->empty-namespace a)
mod ns))
ns)
then I call the script in this namespace, sending it this
(the DrRacket frame%).

Maybe the right thing is for any DrRacket functions that get injected into the scripts namespace to wrap things and go back to the reasonable context.

The tab creation sets up a new DrRacket environment (to run user programs) and maybe that’s what’s failing here.

Are you creating separate threads to run scripts on?

No, I just do: (parameterize ([current-namespace ns])
(let ([f (dynamic-require file fun)]
[<some-args> ...]
(apply f <some-args>)))
where f is the function received from the script

Probably the startup of a user program (which the new tab does) requires the current namespace to be the original drr namespace.

I am not really sure what the hidden invariants of these methods are, tho.

The namespace anchor is not enough then?

The namespace anchor creates a new namespace.

right

So that would be a different namespace.

ok

Maybe just worth trying to see?

If that’s the issue then we can discuss how best to arrange things so that script authors don’t suffer too much

you mean remove the namespace altogether and run directly? I’ll try

Yes, it works

Or paramètreriez to put it back before the call

(did you just include a french word in the middle of your sentence? :smile: )

Not sure what you mean though, put what back?

parameterize

My phone autocompletes in French sometimes.

I see :slightly_smiling_face:

I guess I could send the namespace to the script, so that the script could parameterize correctly, just for a function call?

Looks dirty though

The more I think about this the more I think it would be better to insist that scripts are in modules and then you just don’t need to make any new namespaces

Is that feasible?

(sending the namespace works)

scripts are in modules

Hm…. wait, did I really over-engineer it then?

Why do I need a new namespace…?

Oh! I figured it was because scripts used the top level.

But I didn’t actually look to see! Sorry!

Maybe just not creating a namespace is the best way.

But there are security issues with scripts.

If they were to be isolated then that would probably defeat a lot of useful things.

Yeah so I guess just not making a new namespace is best?

ah, one problem is that if you don’t create a new namespace, you can’t edit a script and reload it, because it will have been loaded already. Which means you need to restart drracket

Ah

Do you want new copies of files the script requires or just the one script?

The main file, I mean.

Each time the script is invoked, i want to revisit it from scratch (unless marked ‘persistent’)

(not sure if that answers your question)

Let’s say that a script has a require in it

When I reload that script, do I get the new version of the required file, or the first version of the required file? (I mean, what behavior do you want?)

Currently, I guess (non-persistent—the default) scripts get a new version, while scripts marked persistent require only once

But I’m a little uncertain if that’s desirable though.

The reason I ask is that there may be a different approach that would reload only the one file (and not thjngs it requires)

ah, that’s interesting

Or maybe things in a specific directory possibly.

(that might be backward incompatible though)

I think you can interpose on the “what name does this module have” part of racket and then give the scripts a fresh name every time.

That will cause them to appear as new modules and thus get reloaded

I am not sure this would work but maybe worth exploring

oh, so you require all of them in the global namespace, and give them a new name everytime. I see.

But memory consumption will increase linearly?

Dinno

Dunno

There probably is a way to get rid of them.

But let’s see if this can work at all first.

Look for module declare in the docs

I am not completely sure how this gets invoked but maybe it can make it work

It may be best to move this discussion to the users or dev mailing list

Want me to start the conversation?

Of maybe I will just ask Matthew.

:)

brb

I sent email @laurent.orseau

Thanks for the email with Matthew.

Another simple but inelegant solution is to pass a function do-in-drracket
that takes a thunk, parameterizes with the global namespace and calls the thunk.

Inelegant as in “not transparent for the user”, when the purpose of quickscript is to make things easier… So I’m willing to give your idea some more thought.

(after reading your email more carefully i realize that’s what you said :) )

@wanpeebaw has joined the channel