[plt-scheme] Fixing keybinding-lang.ss
> Let me see... Ok, got it. I'm also not sure if this is the best way to
> do this either, but here's an example that binds M-, to the less than
> sign, and M-. to the greater than sign:
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (module test-keybindings (lib "keybinding-lang.ss" "framework")
> ;; A small demo of how we can make our own keymap handlers
>
> ;; make-handler: string -> handler
> ;; makes a handler that inserts the string s
> (define (make-handler s)
> (lambda (editor event)
> (send editor insert (make-object string-snip% s))))
>
> ;; Some sample bindings:
> (keybinding "M:," (make-handler "<"))
> (keybinding "M:." (make-handler ">")))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Hi everyone,
I've been playing around with this a little more; it looks like the
keybindings language might need some kind of warning in the documentation
saying that the 'keybinding' macro isn't very composable. I had tried
something like:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module test-keybindings (lib "keybinding-lang.ss" "framework")
(define (make-handler s)
(lambda (editor event)
(send editor insert (make-object string-snip% s))))
(define (simple-bind trigger target)
(keybinding trigger (make-handler target)))
(simple-bind "M:," "<")
(simple-bind "M:." ">"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
but this had the surprising behavior of binding both M:. and M:. to the
greater than sign!
The reason for this is because each handler is assigned a
uniquely-identifying name based on the location of the 'keybinding' macro:
;; inside "keybinding-lang.ss" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-syntax (keybinding stx)
(syntax-case stx ()
[(_ key val)
(with-syntax ([src (syntax-source stx)]
[line (syntax-line stx)]
[col (syntax-column stx)]
[pos (syntax-position stx)])
(syntax (#%keybinding key val 'src 'line 'col 'pos)))]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
And unfortunately, this breaks terribly when I try using keybinding as a
function, since my two handlers will collide with the same name.
Would a good solution to this be adding some kind of uniquely identifying
gensym as part of the name? I added a little to the underlying
%keybinding macro in the keybinding-lang language, and things appear to
work a little better.
I've put the updated collects/framework/keybinding-lang.ss file here:
http://hkn.eecs.berkeley.edu/~dyoo/tmp/keybinding-lang.ss
With the small change from:
(let ([name (if (and line col)
(format "~a:~a.~a" src line col)
(format "~a:~a" src pos))]) ...)
to:
(let ([name
(string-append
(symbol->string (gensym)) ":"
(if (and line col)
(format "~a:~a.~a" src line col)
(format "~a:~a" src pos)))] ...)
things are working a little bit better for me now, and I can use the
'keybinding' in a definition without weird side effects.
Does this look ok? I hope this helps!