On Tue, Nov 11, 2008 at 6:01 PM, Nit Khair <sentinel.2001 / gmx.com> wrote:
> Michael Fellinger wrote:
>> I fixed that just today, check it out :)
>> http://github.com/manveru/ver/commit/9fb04aa943e03850c19b0352b519d885826e7f44
>>
>> ^ manveru
>
> Manveru
>
> I have a question regarding the scope of the keybindings. Being new to
> ruby am confused.
>
> Are these done in a global/application scope. I mean :
>
>>      @keyhandler = VER::KeyHandler.new(self)
>>      VER.let :insert do
>>       map(/^([[:print:]])$/){ view.show(@arg) }
>
> Here, i have defined a key handler, but i don't see an object for my key
> mappings.
>
> My application is slightly different from vi - its multi-screen. Take
> alpine e.g. Each screen has its own mappings. I go from menu, to screen
> A, then screen B, then back to menu. All objects in screen A are
> released so the mappings too are. Thus each screen has its own bindings
> mappings.
>
> Am i correct in thinking that as per VER, my entire app would have to
> share the same bindings?

No, mappings are done per mode, and the handling is done via Keyboard,
where you assign the object you want to send your keys to via focus=.
That means, if you go to a menu, menu has to get focus and it should
have a mode, like :menu. Then the mappings from VER.let(:menu){} are
used, those might give focus to another window, which has a mode like
:window...
So bindings are bundled into modes, and if you switch the mode you get
different bindings.
You can also inherit bindings from other modes to keep things DRY, like this:

VER.let :foo do
  map('f'){ view.show('from foo') }
end

VER.let :bar do
  map('b'){ view.show('from bar') }
end

VER.let :duh => [:foo, :bar] do
  map('d'){ view.show('from duh') }
end

This would give :duh the mappings f, b, and d, while :bar only has b
and foo only has f.
All of the blocks are instance_evaled in the scope of KeyHandler,
which provides the possibility for shortcuts to view or other
convenience-methods.

So if you have a view like this:

class Foo
  attr_accessor :mode

  def initialize(message)
    @mode = :example
    @keyhandler = VER::KeyHandler.new(self)
    @message = message
  end

  def hello
    window.printw(@message)
  end

  def other(message)
    Keyboard.focus = self.class.new(message)
  end

  def press(key)
    @keyhandler.press(key)
  end
end

you can do following:

VER.let :example do
  map('h'){ hello }
  map('o'){ other('From Russia, with love') }
end

Keyboard.focus = Foo.new('Hello, World!')

Please note that I didn't really run the code above, but it should
work like that in case i didn't mess up something real bad.
I know that this is quite some overhead, but VER is highly dynamic in
regards to keymappings, just about any key can switch to a different
window, view, or mode, the keyboard focus changes quite often as well.
I also didn't intend this to be used by some other application, so
some of the implementation is quite specific to VER and i'm not sure
how it would work out in another context.
If you have further issues, please consider forking the project and
work it into a shape that suits you better, possibly a library that
VER and your project and just about any app based on ncurses can
share. Handlings keys is a PITA, and this really is just the usually
piling of layers of abstraction, which I don't like, but it seems to
be the only way until someone comes up with a unified way of handling
those keys (maybe next generation terminals in the year 2100).
This also has no handling of unicode yet, which I will need soon, so
no idea how the API will change by then.

^ manveru