Hello Racketeers, A while ago I announced my MessagePack library here and I mentioned that I was needing it for a client library for the Neovim text editor. Since then I have been writing this client library and now I'm at a point where I need help.
Let me first give you some context: Neovim is a fork of Vim which allows people to write remote plugins in any language. Remote plugins are run by a separate process which is a client to the Neovim server. Basically this means I can write Neovim plugin in Racket (given a Racket host) and call functions written in Racket from Neovim and use them in Neovim plugins. For this to work the functions defined in Racket need to tell Neovim about themselves, they need to register their specifications. Here is how the process works: Neovim first searches for paths to remote plugins, in this case the pattern is "rplugin/racket/*" where "rplugin" is a directory of a Neovim plugin. This means there are many such paths that all end in "/rplugin/racket/*". Neovim then passes the list of all these paths on to the Racket client. The client then has to load or require all these plugins so that they can register their specifications. I'll try to capture the sequence of events in a list: 1) Neovim launches 2) It collects a list of all Racket remote plugins, where a remote plugin is either a file ending in ".rkt" or a directory 3) Neovim launches a Racket instance as the client 4) Neovim sends a request to Racket with a list of all the plugin paths 5) Racket has to set up the specifications 6) After Racket responds back Neovim asks for the specifications 7) Racket sends back a hash table containing the specifications Step 5 is the one that is giving me trouble. Here is how the Racket client is launched: racket -eee '(require (file "autoload/host/bootstrap.rkt"))' \ '(require neovim)' \ '(start-host)' The first instructions requires a bootstrapping module which will get the host ready to receive the requests in step 4 - 7. It works, I have tested it. In the bootstrapping module I also want to process the plugins. A remote plugin has to be required so that its side effects are performed. A declaration in a remote plugin could look something like this: (require neovim/rpc) (define (two) 2) (register-function! two #:name "Two" #:sync #t) Ideally both would be wrapped up in a macro, this is just an idea. The point is that the Racket function foo is not supposed to leave the module, but the side effect of registering it in a global table must happen. Here is an idea of what a plugin registration function could look like: (define (load-plugins paths) ;; Process one plugin at a time (define (load-plugin path) ;; Add the path (or its stem) to the search paths ;; Require the plugin (the plugin should register itself) ) (vector-map load-plugin paths) "Loaded plugins") The sequence of paths was received from Nvim as a vector, and I map over every path, requiring the module/collection. The problem is that I cannot use (require (file path)) because the require is not a top- or module level. The question is: what can I do instead? I would like all the side effects that usually go with "require", but since the registration happens via RPC request it cannot be at module level. I can also pass arbitrary arguments to the racket binary, so I don't need to do all the work in Racket. I hope this explanation makes it clear what I'm trying to achieve. Of course if there is a better way of adding a bunch of collections and modules I am open to that as well. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.