tkri 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +2 -0
  2. data/lib/tkri.rb +285 -73
  3. metadata +2 -2
data/README CHANGED
@@ -9,3 +9,5 @@ Launch it by typing 'tkri' at the operating system prompt. You can
9
9
  provide a starting topic as an argument on the command line. Inside the
10
10
  application, type the topic you wish to go to at the address bar, or
11
11
  click on a word in the main text.
12
+
13
+ See the Help menu for more details.
@@ -52,17 +52,84 @@ module Tkri
52
52
  # found on the system will be used. So make sure to put a generic family
53
53
  # name (i.e., one of: 'courier', 'times', 'helvetica') at the end to serve
54
54
  # as a fallback.
55
- '__base__' => { :background => '#ffeeff', :font => { :family => ['Bitstream Vera Sans Mono', 'courier'], :size => 10 } },
55
+ '__base__' => { :background => '#ffeeff', :font => { :family => ['Bitstream Vera Sans Mono', 'Menlo', 'Monaco', 'Courier'], :size => 10 } },
56
56
  'bold' => { :foreground => 'blue' },
57
57
  'italic' => { :foreground => '#6b8e23' }, # greenish
58
58
  'code' => { :foreground => '#1874cd' }, # blueish
59
- 'header2' => { :background => '#ffe4b5', :font => { :family => ['helvetica'], :size => 16 } },
60
- 'header3' => { :background => '#ffe4b5', :font => { :family => ['helvetica'], :size => 16 } },
59
+ 'header2' => { :background => '#ffe4b5', :font => { :family => ['Geneva', 'Arial', 'Helvetica'], :size => 12 } },
60
+ 'header3' => { :background => '#ffe4b5', :font => { :family => ['Geneva', 'Arial', 'Helvetica'], :size => 14 } },
61
61
  'keyword' => { :foreground => 'red' },
62
62
  'search' => { :background => 'yellow' },
63
63
  'hidden' => { :elide => true },
64
64
  }
65
-
65
+
66
+ BINDINGS = {
67
+ # The keys (e.g. 'b1001') in this hash are named arbitrarily and are completely
68
+ # ignored by Tkri. They exist only to enable you to override certain bindings in
69
+ # your 'rc' file. I'm not going to rename keys, only to add to them (as new
70
+ # bindings are added to newer versions), so you won't have to update your 'rc'
71
+ # file whenever you update Tkri.
72
+
73
+ # For the :key syntax, see the Tk manual. The :source is the widget to attach the
74
+ # binding to. The :commands are methods to execute; they're conveniently prefixed
75
+ # by 'interactive_' to enable you to easily locate all of them in the source code.
76
+
77
+ 'b1001' => { :key => 'Control-q', :source => 'root', :command => 'interactive_quit' },
78
+ 'b1002' => { :key => 'Control-t', :source => 'root', :command => 'interactive_new_tab' },
79
+ 'b1003' => { :key => 'Control-w', :source => 'root', :command => 'interactive_close_tab' },
80
+ 'b1004' => { :key => 'Control-l', :source => 'root', :command => 'interactive_focus_address' },
81
+
82
+ # Note: tabs indexes are zero-based.
83
+ 'b2001' => { :key => 'Alt-Key-1', :source => 'root', :command => 'interactive_switch_to_tab_0' },
84
+ 'b2002' => { :key => 'Alt-Key-2', :source => 'root', :command => 'interactive_switch_to_tab_1' },
85
+ 'b2003' => { :key => 'Alt-Key-3', :source => 'root', :command => 'interactive_switch_to_tab_2' },
86
+ 'b2004' => { :key => 'Alt-Key-4', :source => 'root', :command => 'interactive_switch_to_tab_3' },
87
+ 'b2005' => { :key => 'Alt-Key-5', :source => 'root', :command => 'interactive_switch_to_tab_4' },
88
+ 'b2006' => { :key => 'Alt-Key-6', :source => 'root', :command => 'interactive_switch_to_tab_5' },
89
+ 'b2007' => { :key => 'Alt-Key-7', :source => 'root', :command => 'interactive_switch_to_tab_6' },
90
+ 'b2008' => { :key => 'Alt-Key-8', :source => 'root', :command => 'interactive_switch_to_tab_7' },
91
+ 'b2009' => { :key => 'Alt-Key-9', :source => 'root', :command => 'interactive_switch_to_tab_8' },
92
+ 'b2010' => { :key => 'Alt-Key-0', :source => 'root', :command => 'interactive_switch_to_tab_9' },
93
+
94
+ # For the following we don't use interactive_close_tab because we want to close the
95
+ # tab associated with the button, not the current tab.
96
+ 'b1007' => { :key => 'Button-2', :source => 'tabbutton', :command => 'interactive_close_button_tab' },
97
+
98
+ # 'Prior' and 'Next' are page up and page down, respectively.
99
+ 'b1005' => { :key => 'Control-Key-Prior', :source => 'root', :command => 'interactive_switch_to_prev_tab' },
100
+ 'b1006' => { :key => 'Control-Key-Next', :source => 'root', :command => 'interactive_switch_to_next_tab' },
101
+
102
+ 'b1008' => { :key => 'ButtonRelease-1', :source => 'info', :command => 'interactive_goto_topic_under_mouse' },
103
+ 'b1008b' => { :key => 'Control-Button-1', :source => 'info', :command => 'interactive_goto_topic_under_caret_or_selected', :cancel_default => true },
104
+ 'b1011' => { :key => 'Key-Return', :source => 'info', :command => 'interactive_goto_topic_under_caret_or_selected', :cancel_default => true },
105
+ 'b1012' => { :key => 'Key-Return', :source => 'addressbox', :command => 'interactive_goto_topic_in_addressbox' },
106
+ # If I make the following "ButtonRelease-2" instead, the <PasteSelection>
107
+ # cancellation that follows won't work. Strange.
108
+ 'b1009' => { :key => 'Button-2', :source => 'info', :command => 'interactive_goto_topic_under_mouse_in_new_tab', :cancel_default => true },
109
+ # Under X11, Button-2 is also used to paste the selection. So we disable pasting. All
110
+ # because Tk doesn't support read-only text widgets.
111
+ 'b1010' => { :key => '<PasteSelection>', :source => 'info', :cancel_default => true },
112
+
113
+ # History.
114
+ 'b1013' => { :key => 'ButtonRelease-3', :source => 'info', :command => 'interactive_history_back' },
115
+ 'b1014' => { :key => 'Key-BackSpace', :source => 'info', :command => 'interactive_history_back', :cancel_default => true },
116
+
117
+ # Tk doesn't support read-only rext widgets. So for every "ascii" global binding we also
118
+ # need to duplicate it on the 'info' widget, :cancel_default'ing it.
119
+ #
120
+ # "Global" bindings are those attached to the 'root' window. For "ascii" bindings make sure
121
+ # to turn on :when_not_tkentry, or else these events will fire up when the key is pressed in
122
+ # the addressbox too (which is a widget of type TkEntry).
123
+ 'b1015' => { :key => 'Key-slash', :source => 'root', :command => 'interactive_initiate_search', :when_not_tkentry => true },
124
+ 'b1016' => { :key => 'Key-n', :source => 'root', :command => 'interactive_search_next', :when_not_tkentry => true },
125
+ 'b1017' => { :key => 'Key-N', :source => 'root', :command => 'interactive_search_prev', :when_not_tkentry => true },
126
+ 'b1018' => { :key => 'Key-u', :source => 'root', :command => 'interactive_go_up', :when_not_tkentry => true },
127
+ 'b1019' => { :key => 'Key-slash', :source => 'info', :command => 'interactive_initiate_search', :cancel_default => true },
128
+ 'b1020' => { :key => 'Key-n', :source => 'info', :command => 'interactive_search_next', :cancel_default => true },
129
+ 'b1021' => { :key => 'Key-N', :source => 'info', :command => 'interactive_search_prev', :cancel_default => true },
130
+ 'b1022' => { :key => 'Key-u', :source => 'info', :command => 'interactive_go_up', :cancel_default => true },
131
+ }
132
+
66
133
  # Dump these settings into an 'rc' file.
67
134
  def self.dump
68
135
  require 'yaml'
@@ -75,15 +142,20 @@ module Tkri
75
142
  f.puts "# You may erase any setting in this file for which you want to use"
76
143
  f.puts "# the default value."
77
144
  f.puts "#"
78
- f.puts({ 'command' => COMMAND, 'tags' => TAGS }.to_yaml)
145
+ f.puts({ 'command' => COMMAND, 'tags' => TAGS, 'bindings' => BINDINGS }.to_yaml)
79
146
  end
80
147
  end
81
148
 
82
149
  end # module DefaultSettings
83
150
 
151
+ class << self
152
+ attr_accessor :the_application
153
+ end
154
+
84
155
  module Settings
85
156
  COMMAND = DefaultSettings::COMMAND.dup
86
157
  TAGS = DefaultSettings::TAGS.dup
158
+ BINDINGS = DefaultSettings::BINDINGS
87
159
 
88
160
  # Load the settings from the 'rc' file. We merge them into the existing settings.
89
161
  def self.load
@@ -93,6 +165,7 @@ module Tkri
93
165
  if settings.instance_of? Hash
94
166
  COMMAND.merge!(settings['command']) if settings['command']
95
167
  TAGS.merge!(settings['tags']) if settings['tags']
168
+ BINDINGS.merge!(settings['bindings']) if settings['bindings']
96
169
  end
97
170
  end
98
171
  end
@@ -117,6 +190,29 @@ def self.hash_to_configuration(hash)
117
190
  return ret
118
191
  end
119
192
 
193
+ # Attachs Settings::BINDINGS to a certain widget.
194
+ def self.attach_bindings(widget, widget_id_string)
195
+ Tkri::Settings::BINDINGS.each_pair { |ignored_key, b|
196
+ if (b[:source] == widget_id_string)
197
+ keys = Array(b[:key])
198
+ if b[:key] == 'Key-Return'
199
+ keys.push 'Key-KP_Enter'
200
+ end
201
+ keys.each { |key|
202
+ widget.bind(key) { |event|
203
+ skip = (b[:when_not_tkentry] and event.widget.class == TkEntry)
204
+ if !skip
205
+ if b[:command] # Sometimes we're only interested in :cancel_default.
206
+ Tkri.the_application.invoke_command(b[:command], event)
207
+ end
208
+ end
209
+ break if b[:cancel_default]
210
+ }
211
+ }
212
+ end
213
+ }
214
+ end
215
+
120
216
  # A Tab encapsulates an @address box, where you type the topic to go to; a "Go"
121
217
  # button; and an @info box in which to show the topic.
122
218
  class Tab < TkFrame
@@ -162,29 +258,46 @@ class Tab < TkFrame
162
258
  @info.tag_configure(name, Tkri::hash_to_configuration(hash))
163
259
  end
164
260
 
165
- # Key and mouse bindings
166
- @address.bind('Key-Return') { go }
167
- @address.bind('Key-KP_Enter') { go }
168
- @info.bind('ButtonRelease-1') { |e| go_xy_word(e.x, e.y) }
169
- # If I make the following "ButtonRelease-2" instead, the <PasteSelection>
170
- # cancellation that follows won't work. Strange.
171
- @info.bind('Button-2') { |e| go_xy_word(e.x, e.y, true) }
172
- @info.bind('Key-Return') { go_caret_word(); break }
173
- @info.bind('Key-KP_Enter') { go_caret_word(); break }
174
- @info.bind('ButtonRelease-3') { |e| back }
175
- @info.bind('Key-BackSpace') { |e| back; break }
176
-
177
- # Tk doesn't support "read-only" text widget. We "disable" the following
178
- # keys explicitly (using 'break'). We also forward these search keys to
179
- # @app.
180
- @info.bind('<PasteSelection>') { break }
181
- @info.bind('Key-slash') { @app.search; break }
182
- @info.bind('Key-n') { @app.search_next; break }
183
- @info.bind('Key-N') { @app.search_prev; break }
261
+ Tkri.attach_bindings @address, 'addressbox'
262
+ Tkri.attach_bindings @info, 'info'
184
263
 
185
264
  @history = []
186
265
  end
187
266
 
267
+ def interactive_history_back e
268
+ back
269
+ end
270
+
271
+ def interactive_goto_topic_in_addressbox e
272
+ go
273
+ end
274
+
275
+ def interactive_goto_topic_under_mouse e
276
+ go_xy_word(e.x, e.y)
277
+ end
278
+
279
+ def interactive_goto_topic_under_mouse_in_new_tab e
280
+ go_xy_word(e.x, e.y, true)
281
+ end
282
+
283
+ def interactive_goto_topic_under_caret_or_selected e
284
+ if get_selection.length > 0
285
+ go get_selection
286
+ else
287
+ go_caret_word()
288
+ end
289
+ end
290
+
291
+ # It seeks RubyTk doesn't support the the getSelected method for Text widgets.
292
+ # So here's a method of our own to get the selection.
293
+ def get_selection
294
+ begin
295
+ @info.get('sel.first', 'sel.last')
296
+ rescue
297
+ ''
298
+ end
299
+ end
300
+
188
301
  # Moves the keyboard focus to the address box. Also, selects all the
189
302
  # text, like modern GUIs do.
190
303
  def focus_address
@@ -193,6 +306,10 @@ class Tab < TkFrame
193
306
  @address.focus
194
307
  end
195
308
 
309
+ def interactive_focus_address e
310
+ focus_address
311
+ end
312
+
196
313
  # Finds the next occurrence of a word.
197
314
  def search_next_word(word)
198
315
  @info.focus
@@ -245,6 +362,13 @@ class Tab < TkFrame
245
362
  end
246
363
  end
247
364
 
365
+ # Go "up". That is, if we're browsing a method, go to the class.
366
+ def interactive_go_up e
367
+ if topic and topic =~ /(.*)(::|#|\.)/
368
+ @app.go $1
369
+ end
370
+ end
371
+
248
372
  # Navigate to the topic mentioned under the mouse cursor (given by x,y
249
373
  # coordinates)
250
374
  def go_xy_word(x, y, newtab=false)
@@ -450,29 +574,32 @@ class Tabsbar < TkFrame
450
574
  build_buttons
451
575
  end
452
576
 
453
- def set_current_tab new
577
+ def set_current_tab_by_index new
454
578
  @buttons.each_with_index do |b, i|
455
579
  b.relief = (i == new) ? 'sunken' : 'raised'
456
580
  end
457
- @tabs.set_current_tab new
581
+ @tabs.set_current_tab_by_index new
458
582
  end
459
583
 
460
584
  def build_buttons
461
585
  @buttons.each { |b| b.destroy }
462
586
  @buttons = []
463
-
464
587
  @tabs.each_with_index do |tab, i|
465
588
  b = TkButton.new(self, :text => (tab.topic || '<new>')).pack :side => 'left'
466
- b.command { set_current_tab i }
467
- b.bind('Button-3') { @tabs.close tab }
589
+ b.command { set_current_tab_by_index i }
590
+ Tkri.attach_bindings b, 'tabbutton'
468
591
  @buttons << b
469
592
  end
470
-
471
593
  plus = TkButton.new(self, :text => '+').pack :side => 'left'
472
594
  plus.command { @tabs.new_tab }
473
595
  @buttons << plus
596
+ set_current_tab_by_index @tabs.current_tab_as_index
597
+ end
474
598
 
475
- set_current_tab @tabs.get_current_tab
599
+ def interactive_close_button_tab e
600
+ if idx = @buttons.index(e.widget)
601
+ @tabs.close @tabs.get(idx)
602
+ end
476
603
  end
477
604
  end
478
605
 
@@ -493,32 +620,80 @@ class Tabs < TkFrame
493
620
  tab = Tab.new(self, @app)
494
621
  tab.focus_address
495
622
  @tabs << tab
496
- set_current_tab(@tabs.size - 1)
497
- @app.refresh_tabsbar
623
+ set_current_tab_by_index(@tabs.size - 1, true)
624
+ # @app.refresh_tabsbar
625
+ end
626
+
627
+ def interactive_new_tab e
628
+ new_tab
629
+ end
630
+
631
+ def get(i)
632
+ @tabs[i]
498
633
  end
499
634
 
500
635
  def close(tab)
501
636
  if (@tabs.size > 1 and i = @tabs.index(tab))
502
637
  @tabs.delete_at i
503
638
  tab.destroy
504
- set_current_tab(@current - 1) if @current >= i and @current > 0
639
+ set_current_tab_by_index(@current - 1) if @current >= i and @current > 0
505
640
  @app.refresh_tabsbar
506
641
  end
507
642
  end
508
643
 
509
- def set_current_tab(new)
510
- self.each_with_index do |tab, i|
511
- if i == new; tab.show; else tab.hide; end
644
+ def set_current_tab_by_index(tab_index, refresh=false)
645
+ if tab_index < @tabs.size
646
+ self.each_with_index do |tab, i|
647
+ if i == tab_index;
648
+ tab.show
649
+ # Unless we focus on the new tab, the focus may stay at the old tab's address box.
650
+ tab.focus
651
+ else
652
+ tab.hide
653
+ end
654
+ end
655
+ @current = tab_index
512
656
  end
513
- @current = new
657
+ @app.refresh_tabsbar if refresh
514
658
  end
515
659
 
516
- def get_current_tab
660
+ def switch_to(tab_index)
661
+ set_current_tab_by_index(tab_index, true)
662
+ end
663
+
664
+ def interactive_switch_to_tab_0 e; switch_to 0; end
665
+ def interactive_switch_to_tab_1 e; switch_to 1; end
666
+ def interactive_switch_to_tab_2 e; switch_to 2; end
667
+ def interactive_switch_to_tab_3 e; switch_to 3; end
668
+ def interactive_switch_to_tab_4 e; switch_to 4; end
669
+ def interactive_switch_to_tab_5 e; switch_to 5; end
670
+ def interactive_switch_to_tab_6 e; switch_to 6; end
671
+ def interactive_switch_to_tab_7 e; switch_to 7; end
672
+ def interactive_switch_to_tab_8 e; switch_to 8; end
673
+ def interactive_switch_to_tab_9 e; switch_to 9; end
674
+
675
+ def interactive_switch_to_prev_tab e
676
+ new = current_tab_as_index - 1
677
+ new = @tabs.size - 1 if new < 0
678
+ set_current_tab_by_index(new, true)
679
+ end
680
+
681
+ def interactive_switch_to_next_tab e
682
+ new = current_tab_as_index + 1
683
+ new = 0 if new >= @tabs.size
684
+ set_current_tab_by_index(new, true)
685
+ end
686
+
687
+ def current_tab_as_index
517
688
  return @current
518
689
  end
519
690
 
520
- def current
521
- @tabs[get_current_tab]
691
+ def current_tab
692
+ @tabs[current_tab_as_index]
693
+ end
694
+
695
+ def interactive_close_tab e
696
+ close current_tab
522
697
  end
523
698
 
524
699
  def each
@@ -531,21 +706,25 @@ end
531
706
 
532
707
  class App
533
708
 
709
+
534
710
  def initialize
535
711
  @root = root = TkRoot.new { title 'Tkri' }
536
712
  @search_word = nil
537
713
 
714
+ Tkri.the_application = self
715
+
538
716
  Settings.load
539
717
 
540
718
  menu_spec = [
541
719
  [['File', 0],
542
- ['Close tab', proc { @tabs.close @tabs.current }, 0, 'Ctrl+W' ],
720
+ ['New tab', proc { execute 'interactive_new_tab' }, 0, 'Ctrl+T' ],
721
+ ['Close tab', proc { execute 'interactive_close_tab' }, 0, 'Ctrl+W' ],
543
722
  '---',
544
- ['Quit', proc { exit }, 0, 'Ctrl+Q' ]],
723
+ ['Quit', proc { execute 'interactive_quit' }, 0, 'Ctrl+Q' ]],
545
724
  [['Search', 0],
546
- ['Search', proc { search }, 0, '/'],
547
- ['Repeat search', proc { search_next }, 0, 'n'],
548
- ['Repeat backwards', proc { search_prev }, 7, 'N']],
725
+ ['Search', proc { execute 'interactive_initiate_search' }, 0, '/'],
726
+ ['Repeat search', proc { execute 'interactive_search_next' }, 0, 'n'],
727
+ ['Repeat backwards', proc { execute 'interactive_search_prev' }, 7, 'N']],
549
728
  # The following :menu_name=>'help' has no effect, but it should have...
550
729
  # probably a bug in RubyTK.
551
730
  [['Help', 0, { :menu_name => 'help' }],
@@ -557,19 +736,6 @@ class App
557
736
  ]
558
737
  TkMenubar.new(root, menu_spec).pack(:side => 'top', :fill => 'x')
559
738
 
560
- root.bind('Control-q') { exit }
561
- root.bind('Control-w') { @tabs.close @tabs.current }
562
- root.bind('Control-l') { @tabs.current.focus_address }
563
-
564
- { 'Key-slash' => 'search',
565
- 'Key-n' => 'search_next',
566
- 'Key-N' => 'search_prev',
567
- }.each do |event, method|
568
- root.bind(event) { |e|
569
- send(method) if e.widget.class != TkEntry
570
- }
571
- end
572
-
573
739
  @tabs = Tabs.new(root, self) {
574
740
  pack :side => 'top', :fill => 'both', :expand => true
575
741
  }
@@ -579,6 +745,31 @@ class App
579
745
  @statusbar = TkLabel.new(root, :anchor => 'w') {
580
746
  pack :side => 'bottom', :fill => 'x'
581
747
  }
748
+
749
+ Tkri::attach_bindings root, 'root'
750
+ end
751
+
752
+ # Invokes an "interactive" command (see Settings::BINDINGS).
753
+ # The command is searched in App, Tabs, Tabsbar, Tab, in this order.
754
+ def invoke_command(command, event)
755
+ possible_targets = [self, @tabs, @tabsbar, @tabs.current_tab]
756
+ possible_targets.each { |target|
757
+ if target.respond_to?(command, true)
758
+ target.send(command, event)
759
+ break
760
+ end
761
+ }
762
+ end
763
+
764
+ # Execute is the same as invoke_command() except that we don't
765
+ # provide an event. It's existence is for aesthetics' sake only.
766
+ # It is used in menus.
767
+ def execute(command)
768
+ invoke_command(command, nil)
769
+ end
770
+
771
+ def interactive_quit e
772
+ exit
582
773
  end
583
774
 
584
775
  def run
@@ -587,8 +778,8 @@ class App
587
778
 
588
779
  # Navigates to some topic. This method simply delegates to the current tab.
589
780
  def go(topic=nil, newtab=false)
590
- @tabs.new_tab if newtab and not @tabs.current.new?
591
- @tabs.current.go topic
781
+ @tabs.new_tab if newtab and not @tabs.current_tab.new?
782
+ @tabs.current_tab.go topic
592
783
  end
593
784
 
594
785
  # Sets the text to show in the status bar.
@@ -599,29 +790,29 @@ class App
599
790
  def refresh_tabsbar
600
791
  @tabsbar.build_buttons if @tabsbar
601
792
  end
602
-
603
- def search_prev
793
+
794
+ def interactive_search_prev e
604
795
  if @search_word
605
- @tabs.current.search_prev_word @search_word
796
+ @tabs.current_tab.search_prev_word @search_word
606
797
  end
607
798
  end
608
-
609
- def search_next
799
+
800
+ def interactive_search_next e
610
801
  if @search_word
611
- @tabs.current.search_next_word @search_word
802
+ @tabs.current_tab.search_next_word @search_word
612
803
  else
613
- search
804
+ interactive_initiate_search nil
614
805
  end
615
806
  end
616
807
 
617
- def search
808
+ def interactive_initiate_search e
618
809
  self.status = 'Type the string to search'
619
810
  entry = TkEntry.new(@root).pack(:fill => 'x').focus
620
811
  ['Key-Return', 'Key-KP_Enter'].each do |event|
621
812
  entry.bind(event) {
622
813
  self.status = ''
623
814
  @search_word = entry.get
624
- @tabs.current.search_next_word entry.get
815
+ @tabs.current_tab.search_next_word entry.get
625
816
  entry.destroy
626
817
  }
627
818
  end
@@ -632,7 +823,7 @@ class App
632
823
  }
633
824
  end
634
825
  entry.bind('KeyRelease') {
635
- @tabs.current.highlight_word entry.get
826
+ @tabs.current_tab.highlight_word entry.get
636
827
  }
637
828
  end
638
829
 
@@ -701,18 +892,34 @@ EOS
701
892
 
702
893
  def help_key_bindings
703
894
  helpbox('Help: Key bindings', <<EOS)
895
+ These are the *default* bindings. They are configurable via the 'rc' file.
896
+
704
897
  Left mouse button
705
898
  Navigate to the topic under the cursor.
899
+ Ctrl + Left mouse button
900
+ Navigate to the topic selected (marked) with the mouse.
706
901
  Middle mouse button
707
902
  Navigate to the topic under the cursor. Opens in a new tab.
708
903
  Right mouse button
709
904
  Move back in the history.
710
- Ctrl+W. Or right mouse button, on a tab button
905
+ Ctrl+W. Or middle mouse button, on a tab button
711
906
  Close the tab (unless this is the only tab).
712
907
  Ctrl+L
713
908
  Move the keyboard focus to the "address" box, where you can type a topic.
909
+ Ctrl+T
910
+ New tab.
911
+ Alt-1 .. Alt-9, Ctrl-PgUp, Ctrl-PgDn
912
+ Swith to a certain, or to the next/previous one.
913
+ u
914
+ Goes "up" one level. That is, if you're browsing Module::Class#method,
915
+ you'll be directed to Module::Class. Press 'u' again for Module.
916
+ Enter
917
+ Go to the topic under the caret, or, if some text is selected, to the
918
+ topic selected.
714
919
  /
715
- Find string in page.
920
+ Find string in page.
921
+ n, N
922
+ Jump to next/previous finds.
716
923
  EOS
717
924
  end
718
925
 
@@ -737,6 +944,11 @@ Left-clicking on a word doesn't yet send you to a new page. It's
737
944
  *releasing* the button that sends you there. This makes it possible to
738
945
  select pieces of code: left-click, then drag, then release; since some
739
946
  text is now selected, Tkri figures out that's all you wanted.
947
+
948
+ When using Enter to go to a selected (marked) topic, note that it's easier
949
+ to hit the Enter of the keypad, with your thumb, because it's near the
950
+ mouse (provided you're right-handed). As a bonus, you can navigate with one
951
+ hand only.
740
952
  EOS
741
953
  end
742
954
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tkri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mooffie
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-26 00:00:00 +02:00
12
+ date: 2009-10-29 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency