Class: Keys

Inherits:
Object show all
Defined in:
lib/xiki/keys.rb

Overview

Methods for defining keyboard shortcuts

Constant Summary collapse

@@key_queue =

For defining menus (must be done in reverse)

[]

Class Method Summary collapse

Class Method Details

.add_menu_itemsObject



660
661
662
663
664
665
# File 'lib/xiki/keys.rb', line 660

def self.add_menu_items
  @@key_queue.reverse.each do |i|
    Menu.add_item [Menu::ROOT_MENU, i[0]], i[1], "#{i[0].downcase}-#{i[1].downcase.gsub(' ', '-')}"
  end
  @@key_queue = []
end

.add_prefix(new_prefix) ⇒ Object

Set prefix, or append it (space-delimited) if one already there.



535
536
537
538
539
540
541
# File 'lib/xiki/keys.rb', line 535

def self.add_prefix new_prefix
  prefix = self.prefix

  return self.prefix = new_prefix if ! prefix   # If none there already, just set it

  self.prefix = "#{self.prefix} #{new_prefix}"
end

.apiObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/xiki/keys.rb', line 140

def self.api
  '
  > Summary
  | Ways to use the Keys class, to define keyboard shortcuts etc.  Remember
  | that with xiki shortcuts you hold down the control key and "type the
  | acronym" (the first letter in each word) while holding down the control
  | key.
  |
  > Define keyboard shortcuts
  | Defines the key Control-e Control-y
  |
  |   Keys.enter_name { View << "Steve" }
  |
  | Defines the key Control-e Control-y (with no mnemonic)
  |
  |   Keys.EN { View << "Steve again" }
  |
  > Where to put them
  | You can put keyboard shortcuts into any file that gets required by xiki.
  | For example, you could create a file like this:
  |
  - @~/my_xiki_stuff/
    - keys.rb
      | # My shortcuts
      | Keys.enter_name { View << "Steve" }
      | Keys.enter_yay { View << "Yay" }
  |
  | Then you could require this file when xiki loads by adding this line:
  |
  - @~/.el4r/
    - init.rb
      | require "~/my_xiki_stuff/keys"
  '
end

.as(name) ⇒ Object



514
515
516
517
518
519
# File 'lib/xiki/keys.rb', line 514

def self.as name
  Clipboard.copy("#{name}")
  Bookmarks.save("$#{name}")
  Bookmarks.save("$_#{name}")
  View.save("#{name}")
end

.before_lastObject



720
721
722
# File 'lib/xiki/keys.rb', line 720

def self.before_last
  $el.el4r_lisp_eval("(elt (recent-keys) (- (length (recent-keys)) 2))").to_s
end

.bookmark_as_path(options = {}) ⇒ Object



615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
# File 'lib/xiki/keys.rb', line 615

def self.bookmark_as_path options={}
  bm = options[:bm] || Keys.input(:timed=>true, :prompt=>options[:prompt]||"Enter a bookmark: ")

  if bm == " "   # If space, return special token
    return :space
  elsif bm == "/"   # If slash, return special token
    return :slash
  elsif bm == "x"   # If slash, return special token
    return Xiki.dir
  elsif bm == ","   # If slash, return special token
    return :comma
  elsif bm =~ /^\.+$/   # If .+ do tree in current dir
    dir = View.dir :force_slash
    (bm.size - 1).times do
      dir.sub! /\/$/, ''   # Remove / on end if there
      dir.sub! /[^\/]+$/, ''   # Remove dir
    end
    dir.sub! /^$/, '/'   # If nothing left, use root (/)
    return dir
  end

  dir = Bookmarks.expand bm, :just_bookmark=>true
  if dir.nil?   # If no dir, return nil
    View.beep "- Bookmark '#{bm}' doesn't exist."
    return :bookmark_doesnt_exist
  end

  unless options[:include_file]
    dir = Bookmarks.dir_only dir
    dir << "/" unless dir =~ /\/$/
  end
  dir

end

.charObject



667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
# File 'lib/xiki/keys.rb', line 667

def self.char
  $el.elvar.inhibit_quit = true
  ch_initial = $el.read_event.to_s
  $el.elvar.inhibit_quit = nil

  if ch_initial =~ /^\d+$/   # If a number, assign it to raw
    ch_raw = ch_initial.to_i
    if 134217825 <= ch_raw and ch_raw <= 134217850  # If meta (out of elisp range)
      return ["meta_#{(ch_raw - 134217728).chr}".to_sym, nil]
    end

    # Special check for C-. and other sequences
    ch = if ch_raw == 67108910
      :control_period
    elsif ch_raw >= 67108912 && ch_raw <= 67108921   # If between C-0 and C-9
      (ch_raw - 67108864).chr
    elsif ch_raw == 67108911
      :control_slash
    else
      # If char is over the elisp max, try to interpret it as Meta
      $el.char_to_string(ch_raw)
    end
    return [ch, ch_raw]

  elsif ['left', 'right', 'up', 'down', ].member?(ch_initial)
    return [ch_initial.to_sym, 0]   # Arbitrary indicator for arrow keys

  elsif ch_initial == "C-return"
    return [:control_return, 13]

  elsif ch_initial == "return"
    return [:return, 13]

  elsif ch_initial == "backspace"
    return [:backspace, 127]

  elsif ch_initial == "tab"
    return ["\t", 9]

  else   # Probably a mouse event
    return [nil, nil]
  end

end

.clear_prefixObject



611
612
613
# File 'lib/xiki/keys.rb', line 611

def self.clear_prefix
  $el.elvar.current_prefix_arg = nil
end

.delete?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


592
593
594
# File 'lib/xiki/keys.rb', line 592

def self.delete? options={}
  self.prefix == "delete"
end

.historyObject



724
725
726
727
# File 'lib/xiki/keys.rb', line 724

def self.history
  $el.view_lossage
  View.flash "- Showed recently-typed keys in other view!", :times=>4
end

.human_readable(txt) ⇒ Object



745
746
747
# File 'lib/xiki/keys.rb', line 745

def self.human_readable txt
  txt.split(/[^a-z]/i).map{|o| "Control-#{o[/./].upcase}"}.join(" ")
end

.input(*args) ⇒ Object

Gets input from user.

Sample usages: Keys.input # Terminated by enter Keys.input “Type something: ” Keys.input :chars=>1 # Just one char Keys.input :timed=>1 # Terminated by pause Keys.input :optional=>1 # Terminated by pause

- A pause at the beginning will result in no input (nil)


306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/xiki/keys.rb', line 306

def self.input *args

  prompt = args.shift if args[0].is_a?(String)

  options = args[0] || {}

  return self.input_with_choices(options) if options[:choices]

  Cursor.remember :before_input

  # This is slow in mac emacs 23/24 :(
  # Cursor.green

  Cursor.hollow

  prompt ||= options[:prompt] || "Input: "

  if options[:chars]
    char = $el.char_to_string(
      self.remove_control($el.read_char(prompt))).to_s
    Cursor.restore :before_input
    return char
  end

  # If simple un-timed input, just get string and return it
  unless options[:timed] || options[:optional]
    Cursor.restore :before_input
    c = $el.read_string(prompt, options[:initial_input])
    return c
  end

  keys = ""

  $el.elvar.inhibit_quit = true
  c = nil

  # If not optional, wait for input initially
  unless options[:optional]
    c = $el.read_char(prompt)
    keys = self.to_letter(c)
  end

  if c == 7
    Cursor.restore :before_input
    $el.elvar.inhibit_quit = nil
    $el.keyboard_quit
  end

  while(c = $el.read_char("#{prompt}#{keys}", nil, 0.35))
    keys += self.to_letter(c)
    if c == 7
      Cursor.restore :before_input
      $el.elvar.inhibit_quit = nil
      $el.keyboard_quit
    end
  end
  $el.elvar.inhibit_quit = nil
  Cursor.restore :before_input

  $el.message ""
  # If nothing, return nil
  keys == "" ? nil : keys
end

.input_with_choices(options) ⇒ Object

TODO: finish - look at spec



371
372
373
374
375
376
377
378
# File 'lib/xiki/keys.rb', line 371

def self.input_with_choices options
  prompt = options[:prompt] ? "#{options[:prompt]} " : ""
  prompt << options[:choices].map{|i|
    "[#{i.first[/./]}]#{i.first[/.(.+)/,1]}"}.
    join(', ')
  c = Keys.input :chars=>1, :prompt=>prompt
  options[:choices].find{|i| i.first =~ /^#{c}/}[1]
end

.insert_codeObject



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/xiki/keys.rb', line 410

def self.insert_code
  keys = $el.read_key_sequence("Type some keys, to insert the corresponding code: ")

  # If C-n or C-p, pretend like they were mapped to xiki functions

  if keys == "\cn"
    return View << 'Line.next'
  elsif keys == "\cp"
    return View << 'Line.previous'
  end

  proc = self.proc_from_key keys

  # If lisp, enter lisp?
  if proc.nil?
    keys = $el.key_binding(keys)
    if keys
      return View.insert($el.prin1_to_string(keys))
    else
      $el.beep
      return View.message("Key is unmapped")
    end
  end

  code = Code.to_ruby(proc)
  code.gsub! 'proc { ', ''
  code.gsub! ' }', ''

  code.gsub! '(:blink => (true))', ''

  View << code
end

.insert_from_qObject



521
522
523
524
525
# File 'lib/xiki/keys.rb', line 521

def self.insert_from_q
  ($el.elvar.current_prefix_arg || 1).times do
    View.insert($el.elvar.qinserted)
  end
end

.isearch_prefix(shortcut_length = 2) ⇒ Object



729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# File 'lib/xiki/keys.rb', line 729

def self.isearch_prefix shortcut_length=2
  # TODO Make search.stop set Keys.prefix (call .isearch_prefix)
    # Keys.prefix = self.isearch_prefix
  # and don't call .isearch_prefix

  # What about shortcut_length though?  Would we get weird results for search_foo_foo shortcuts? - just try it for now

  # Return it if character before key shortcut was C-u or C-0 - C-9...
  char = Keys.last(shortcut_length+1).to_i
  return :u if char == 21
  return :- if char == 67108909
  return (char - 67108912) if char >= 67108912 && char <= 67108921

  nil
end

.jump_to_codeObject



443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/xiki/keys.rb', line 443

def self.jump_to_code
  keys = $el.read_key_sequence("Type some keys, to jump to the corresponding code: ")
  proc = self.proc_from_key keys
  if proc.nil?
    $el.beep
    return View.message("Key isn't mapped in Xiki")
  end

  file, line = Code.location_from_proc proc
  file = "#{Xiki.dir}#{file}" unless file =~ /^\//
  Location.go(file)
  View.to_line line.to_i
  Effects.blink(:what=>:line)
end

.last(nth = 1) ⇒ Object



716
717
718
# File 'lib/xiki/keys.rb', line 716

def self.last nth=1
  $el.el4r_lisp_eval("(elt (recent-keys) (- (length (recent-keys)) #{nth}))").to_s
end

.map_to_eval(keys_raw, code) ⇒ Object



261
262
263
264
265
266
267
# File 'lib/xiki/keys.rb', line 261

def self.map_to_eval keys_raw, code
  $el.el4r_lisp_eval"
    (global-set-key (kbd \"#{keys_raw}\")  (lambda () (interactive)
      (el4r-ruby-eval \"#{code}\" )
    ))
    "
end


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/xiki/keys.rb', line 11

def self.menu
  %`
  - .history/
  - .api/
    > Map C-c C-a
    | Keys.CA { View.insert "foo" }

    > Map C-d C-h
    | Keys.do_hi { Line << "hey there" }

    > Map M-x (in shell mode)
    | Keys._X(:shell_mode_map) { View.insert "foooo" }

    > Get user input
    | - A String
    |   - puts Keys.input(:prompt => "Name: ")
    | - Just one char
    |   - puts Keys.input :chars=>1
  - docs/
    - Summary/
      > Xiki Shortcuts
      | Xiki has keyboard shortcuts predefined for doing all kinds of things.
      | Each keyboard shortcut has a mnemonic. Check out the "Keys" menu bar
      | menu for a quick look at them.

      | And Xiki lets you define your own keyboard shortcuts.  This line makes
      | Control-e Control-n insert "Steve".

      |   Keys.EN { View << "Steve" }

      | For more about defining your own keyboard shortcuts see:
      - @keys/api/

      > Xiki's "type the acronym" approach
      | Each xiki keyboard shortcut has a mnemonic that helps you
      | simultaneously remember what it does and how to type it.

      | For example, given this mnemonic:

      |   layout_create

      | you type:

      |   Control-l Control-c  (l for "layout" and c for "create")

      > Reasons for this appoarch
      - More possible shortcuts/
        | The approach of having single character key shortcuts (e.g. Control-a)
        | works nicely for apps that have a small number of shortcuts. But it
        | becomes less elegant when more shortcuts are used (Ctrl-a, Alt-a,
        | Ctrl-Shift-a).

        | The "type the acronym" approach with just the Control
        | key allows for very a large number of key shortcuts that are less
        | prone to get confused with one another.

      - Less to remember/
        | A mnemonic clues you into what the keyboard shortcut does and how to type it,
        | so it's all you need to remember. There's no need to separately remember a keyboard shortcut and what it does (a
        | challenging part of most keyboard shortcut schemes having a large number of
        | shortcuts, which xiki attempts to avoid).

        | Doesn't sound like standard emacs shortcuts?  Here's an explanation about
        | how xiki deals with existing emacs shortcuts.

      - emacs_shortcuts/
        | TODO add stuff about how C-a turns into C-a C-a, etc.
        | Mention how this lets a large number of key shortcuts without interfering
        | with emacs shortcuts.
        | But an admitted downside is it affects 6 existing emacs shortcuts
        | and makes you type them twice.
        | In practice the annoyance caused by this isn't as bad as it initially may seem
        | Consider using to_axis instead of C-a C-a and to_end instead of C-e C-e.

    > Six categories
    | As you can see by looking at the "Keys" menu in the menu bar, there are
    | six main categories of key shortcuts.

    - Descriptions of each category/
      - to: jumping to specific points
      - open: opening things
      - layout: views and windows
      - as: remembering things
      - enter: inserting things
      - do: executing things

    > Examples
    | Here are some of the most commonly used shortcuts in each category.
    | (Double-click a category to see them.)

    - to/
      | to+highest: Jump to top of file
      | to+lowest: Jump to bottom of file
      | to+axis: Jump to beginning of line
      | to+end: Jump to end of line
    - open/
      | open+bookmark: view a bookmark
      | open+tree: view a tree of a directory
      | open+current: shows currently open files
      | open+edited: shows recently edited files
      | open+history: shows recently viewed files
      | open+menu: opens view that lets you type a menu (type "-" to see all)
    - layout/
      | layout+create: Create a new view
      | layout+hide: Hide this view
      | layout+next: Go to next view
      | layout+previous: Go to previous view
      | layout+kill: Close the current file
    - as/
      | as+clipboard: Copy (after doing Control-space on the other side)
      | as+kill: Cut (after doing Control-space on the other side)
      | as+bookmark: remember this file as a bookmark
    - enter/
      | enter+clipboard: Paste
    - do/
      | do+tree: view an expanded tree of a directory
    - miscellaneous/
      | Control-tab: cycles through files

    | For all keyboard shortcuts, see where they're key_bindings.rb, where they're
    | defined:
    - @$xiki/key_bindings.rb

    > Keyboard shortcuts while searching
    | The seventh category, "search" has special behavior.  See:
    - @search/docs/
  `
end

.method_missing(meth, *args, &block) ⇒ Object

Handles Keys.to_foo etc.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/xiki/keys.rb', line 178

def self.method_missing(meth, *args, &block)

  return if ! $el

  # Accept it if block but no args
  meth = meth.to_s

  meth_orig = meth.dup


  # Delegate to super unless arg is single symbol
  unless args.size == 0 or (args.size == 1 and args[0].is_a? Symbol)
    return super(meth, *args, &block)
  end

  meth_title = meth.gsub('_', ' ').gsub(/\b\w/) {|s| s.upcase}
  menu, item = meth_title.match(/(.+?) (.+)/)[1..2] if meth_title =~ /. ./

  # If 1st word is 'isearch', use it as map
  if meth =~ /^search_/
    @@key_queue << ["Search", item]
    meth.sub! /^search_/, ''
    meth = self.words_to_letters meth
    args = [:isearch_mode_map]
  elsif meth =~ /[A-Z]/   # If capital letters
    # Don't convert
  elsif meth =~ /_/   # Add menu item, if more than one word

    if args.size == 0   # If global keymap
      # Make lisp function
      $el.defun(meth.to_sym, :interactive=>true) do
        block.call
      end
      @@key_queue << [menu, item]
    end

    # Change 'to_foo' to 'TF' etc
    meth = self.words_to_letters meth
  end

  keys_raw = self.translate_keys meth   # Translate to 'C-t C-f' etc

  keys = $el.kbd keys_raw   # Translate to actual control keys

  map = :global_map   # Default to global keymap

  # Use keymap if symbol passed as 1st arg
  map = args.shift if args[0] and args[0].class == Symbol
  # If they just passed a string, use it as code
  if args and (args.size == 1) and !block
    self.map_to_eval keys_raw, args[0]
    return
  end

  #     # Add menus for key shortcuts - seems kind of pointless in retrospect
  #     if map == :global_map && meth_orig =~ /^[a-z]/
  #       Launcher.add(meth.downcase, &block)
  #       Launcher.add(meth_orig, &block)   # if meth_orig =~ /^[a-z]/
  #     end

  # Define key
  begin
    $el.define_key map, keys, &block
    "- key was defined: #{keys_raw}"
  rescue Exception => e
    return if map != :global_map || meth !~ /([A-Z])([A-Z]?)./   # Only global map and 2 control keys
    message = e.message
    prefix = message[/"Key sequence .+? starts with non-prefix key (.+?)"/, 1]
    return if prefix.nil?

    prefix = $el.kbd(prefix)

    begin   # If it appears to be a prefix key (already defined)
      $el.global_unset_key(prefix)
      $el.define_key map, keys, &block

    rescue Exception => e
      Ol << "e (inner): #{e.inspect}"
    end

  end
end

.open?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


596
597
598
# File 'lib/xiki/keys.rb', line 596

def self.open? options={}
  self.prefix == "open"
end

.prefix(options = {}) ⇒ Object



543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
# File 'lib/xiki/keys.rb', line 543

def self.prefix options={}
  pre = $el.elvar.current_prefix_arg
  return nil unless pre

  # Clear prefix if :clear
  $el.elvar.current_prefix_arg = nil if options[:clear]
  str = pre.to_s

  return :u if str == "u"

  if str =~ /^\(/
    return :uu if str == "(16)"
    return :uuu if str == "(64)"
    return :u
  end

  return :- if "#{pre}" == "-"
  return pre
end

.prefix=(to) ⇒ Object



563
564
565
# File 'lib/xiki/keys.rb', line 563

def self.prefix= to
  $el.elvar.current_prefix_arg = to
end

.prefix_n(options = {}) ⇒ Object



600
601
602
603
604
605
# File 'lib/xiki/keys.rb', line 600

def self.prefix_n options={}
  pre = self.prefix(options)
  return pre if pre.is_a?(Fixnum)
  return $&.to_i if pre.is_a?(String) && pre =~ /\d+/
  nil
end

.prefix_or_0(options = {}) ⇒ Object



527
528
529
530
# File 'lib/xiki/keys.rb', line 527

def self.prefix_or_0 options={}
  pre = Keys.prefix
  pre.is_a?(Fixnum) ? pre : 0
end

.prefix_timesObject



650
651
652
653
654
655
656
657
658
# File 'lib/xiki/keys.rb', line 650

def self.prefix_times
  prefix = self.prefix
  case prefix
  when nil, :u, :uu, :uuu
    1
  else
    prefix
  end
end

.prefix_u(options = {}) ⇒ Object

Whether C-u was held down before this Deprecated



574
575
576
577
578
# File 'lib/xiki/keys.rb', line 574

def self.prefix_u options={}
  result = self.prefix == :u
  self.clear_prefix if options[:clear]
  result
end

.prefix_u?Boolean

Whether C-u was held down before this

Returns:

  • (Boolean)


568
569
570
# File 'lib/xiki/keys.rb', line 568

def self.prefix_u?
  self.prefix == :u
end

.prefix_uuObject



607
608
609
# File 'lib/xiki/keys.rb', line 607

def self.prefix_uu
  self.prefix == :uu
end

.proc_from_key(keys) ⇒ Object



458
459
460
461
462
463
464
465
# File 'lib/xiki/keys.rb', line 458

def self.proc_from_key keys
  code = $el.prin1_to_string($el.key_binding(keys))
  # If it is a call to elisp
  id = code[/el4r-ruby-call-proc-by-id.+?([_0-9]+)/, 1]
  return nil if id.nil?

  ObjectSpace._id2ref(id.to_i)
end

.read_char_maybeObject



399
400
401
402
403
404
405
406
407
408
# File 'lib/xiki/keys.rb', line 399

def self.read_char_maybe
  loc = $el.read_char("Optionally type a char:", nil, 0.35)
  $el.message ""
  return if loc.nil?

  # Convert control chars to the corresponding letters
  loc += 96 if(1 <= loc and loc <= 26)
  loc = self.remove_control loc
  loc
end

.remove_control(ch) ⇒ Object

Converts any control keys in input to normal keys. Example: “C-x” => “x”



394
395
396
397
# File 'lib/xiki/keys.rb', line 394

def self.remove_control ch
  ch += 96 if ch < 27
  ch
end

.set(*args, &block) ⇒ Object



284
285
286
287
288
289
290
291
292
293
# File 'lib/xiki/keys.rb', line 284

def self.set *args, &block

  # Keys is always first arg
  keys = args.shift
  if args.size > 0   # If 2nd arg, use it
    self.map_to_eval keys, args[0]
  else   # Otherwise, use block
    $el.define_key :global_map, $el.kbd(keys), &block
  end
end

.timed_insert(options = {}) ⇒ Object



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/xiki/keys.rb', line 467

def self.timed_insert options={}
  prefix = Keys.prefix
  # If prefix of 0, insert in a way that works with macros
  case prefix
  when nil   # Do nothing
  when :u   # Do pause for space
    PauseMeansSpace.go
    return
  when 0
    View.insert Keys.input(:prompt => "Insert text to insert: ")
    return
  else   # If other prefix, insert single char n times
    c = View.read_char("Insert single char to insert #{prefix} times: ").chr
    prefix.times do
      View.insert c
    end
    return
  end

  Cursor.remember :before_q
  Cursor.box
  # This is slow in mac emacs 23/24 :(
  # Cursor.green

  # Get first char and insert
  c = $el.read_char("insert text (pause to exit): ").chr
  inserted = "#{c}"

  View.insert c

  # While no pause, insert more chars
  while(c = $el.read_char("insert text (pause to exit): ", nil, 0.36))
    inserted += c.chr
    View.insert c.chr
  end

  $el.elvar.qinserted = inserted
  $el.message "input ended"

  Cursor.restore :before_q

  # Store in hash by first letter for use by enter_yank

  Clipboard.save_by_first_letter inserted   # Store for retrieval with enter_yank

end

.to_letter(ch) ⇒ Object



380
381
382
383
384
385
386
387
388
389
390
# File 'lib/xiki/keys.rb', line 380

def self.to_letter ch
  return nil if ch.nil?
  if ch == 0
    ch = 32
  elsif ch < 27
    ch += 96
  elsif 67108896 <= ch and ch <= 67108921
    ch -= 67108864
  end
  ch.chr
end

.translate_keys(txt) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/xiki/keys.rb', line 269

def self.translate_keys txt
  l = txt.scan(/_?\w/)
  l.collect! { |b|
    case b
    when /^_([A-Z])/
      "M-" + $1.downcase
    when /^([a-z])$/
      $1
    else
      "C-" + b.downcase
    end
  }
  l.join " "
end

.up?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


580
581
582
# File 'lib/xiki/keys.rb', line 580

def self.up? options={}
  self.prefix_u options
end

.update?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


584
585
586
587
588
589
590
# File 'lib/xiki/keys.rb', line 584

def self.update? options={}
  # TODO update so prefix can have multiple values, like C-u and "update"
  #   for when C-u as+update
  #   (space-separated list)?
  #     "u update"
  self.prefix == "update"
end

.words_to_letters(txt) ⇒ Object



712
713
714
# File 'lib/xiki/keys.rb', line 712

def self.words_to_letters txt
  TextUtil.camel_case(txt).gsub(/[a-z]/, '')
end