Class: VER::HoverCompletion

Inherits:
Object
  • Object
show all
Defined in:
lib/ver/hover_completion.rb

Overview

TODO: the positioning behaviour is still annoying, for some reason I just can’t get a handle on a changed position. Even using the tk-internal Expose event works only sometimes.

Defined Under Namespace

Classes: Listbox

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, options = {}, &completer) ⇒ HoverCompletion

Returns a new instance of HoverCompletion.



44
45
46
47
48
49
# File 'lib/ver/hover_completion.rb', line 44

def initialize(parent, options = {}, &completer)
  @parent, @options, @completer = parent, options, completer
  setup_widgets
  setup_events
  update
end

Instance Attribute Details

#choicesObject

Returns the value of attribute choices.



42
43
44
# File 'lib/ver/hover_completion.rb', line 42

def choices
  @choices
end

#completerObject

Returns the value of attribute completer.



42
43
44
# File 'lib/ver/hover_completion.rb', line 42

def completer
  @completer
end

#fromObject

Returns the value of attribute from.



42
43
44
# File 'lib/ver/hover_completion.rb', line 42

def from
  @from
end

#listObject (readonly)

Returns the value of attribute list.



41
42
43
# File 'lib/ver/hover_completion.rb', line 41

def list
  @list
end

#optionsObject

Returns the value of attribute options.



42
43
44
# File 'lib/ver/hover_completion.rb', line 42

def options
  @options
end

#parentObject (readonly)

Returns the value of attribute parent.



41
42
43
# File 'lib/ver/hover_completion.rb', line 41

def parent
  @parent
end

#toObject

Returns the value of attribute to.



42
43
44
# File 'lib/ver/hover_completion.rb', line 42

def to
  @to
end

Instance Method Details

#cancelObject



136
137
138
139
# File 'lib/ver/hover_completion.rb', line 136

def cancel
  list.destroy
  parent.focus
end

#continue_completionObject



63
64
65
66
# File 'lib/ver/hover_completion.rb', line 63

def continue_completion
  pick
  options[:continue] ? update : cancel
end

#layoutObject



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
# File 'lib/ver/hover_completion.rb', line 93

def layout
  return unless choices && choices.size > 0

  x, y, caret_height =
    parent.tk_caret.values_at(:x, :y, :height)

  height, width = parent.winfo_height, parent.winfo_width
  height -= parent.status.winfo_height

  # use side with most space, east or west
  if x > (width / 2)
    side = 'e'
  else
    side = 'w'
  end

  # use hemisphere with most space
  if y < (height / 3)
    hemisphere = 'n'
    y += caret_height
    height -= y
  elsif y < (height / 2)
    hemisphere = ''
    height -= ((height - y) / 2)
  else
    hemisphere = 's'
    height -= (height - y)
  end

  list.configure width: @longest_choice + 2, height: -1
  height = [height, list.winfo_reqheight].min
  width = [width, list.winfo_reqwidth].min

  list.place(
    x: x,
    y: y,
    height: height,
    width: width,
    in: parent,
    anchor: "#{hemisphere}#{side}"
  )
end

#pickObject



73
74
75
76
77
# File 'lib/ver/hover_completion.rb', line 73

def pick
  index = list.curselection.first
  replacement = list.get(index)
  parent.replace(from, to, replacement)
end

#setup_eventsObject



58
59
60
61
# File 'lib/ver/hover_completion.rb', line 58

def setup_events
  list.bind('<<ListboxSelect>>'){ layout }
  list.bind('<Expose>'){ layout }
end

#setup_widgetsObject



51
52
53
54
55
56
# File 'lib/ver/hover_completion.rb', line 51

def setup_widgets
  @list = Listbox.new(parent, borderwidth: 0, selectmode: :single)
  @list.hover_completion = self
  @list.major_mode = :HoverCompletion
  @list.focus
end

#submitObject



68
69
70
71
# File 'lib/ver/hover_completion.rb', line 68

def submit
  pick
  cancel
end

#updateObject



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ver/hover_completion.rb', line 79

def update
  self.from, self.to, self.choices = completer.call
  @longest_choice = choices.map{|choice| choice.size }.max

  if choices && choices.size > 0
    list.value = choices
    list.select 0

    submit if choices.size == 1
  else
    cancel
  end
end