Class: VER::Text

Inherits:
Tk::Text
  • Object
show all
Includes:
Methods
Defined in:
lib/ver/text.rb,
lib/ver/text/index.rb

Defined Under Namespace

Classes: Index

Constant Summary collapse

MODE_CURSOR =
{
  :insert       => {insertbackground: 'red',    blockcursor: false},
  :control      => {insertbackground: 'green',  blockcursor: true},
  :select_char  => {insertbackground: 'yellow', blockcursor: true},
  :select_line  => {insertbackground: 'yellow', blockcursor: true},
  :select_block => {insertbackground: 'yellow', blockcursor: true},
}
GUESS_ENCODING_ORDER =
[
  Encoding::US_ASCII,
  Encoding::UTF_8,
  Encoding::Shift_JIS,
  Encoding::EUC_JP,
  Encoding::EucJP_ms,
  Encoding::Big5,
  Encoding::UTF_16BE,
  Encoding::UTF_16LE,
  Encoding::UTF_32BE,
  Encoding::UTF_32LE,
  Encoding::CP949,
  Encoding::Emacs_Mule,
  Encoding::EUC_KR,
  Encoding::EUC_TW,
  Encoding::GB18030,
  Encoding::GBK,
  Encoding::Stateless_ISO_2022_JP,
  Encoding::CP51932,
  Encoding::EUC_CN,
  Encoding::GB12345,
  Encoding::Windows_31J,
  Encoding::MacJapanese,
  Encoding::UTF8_MAC,
  Encoding::BINARY,
]
MATCH_WORD_RIGHT =
/[^a-zA-Z0-9]+[a-zA-Z0-9'"{}\[\]\n-]/
MATCH_WORD_LEFT =
/(^|\b)\S+(\b|$)/
TAG_ALL_MATCHING_OPTIONS =
{ from: '1.0', to: 'end - 1 chars' }

Constants included from Methods::Move

Methods::Move::GO_MATCHING_LEFT, Methods::Move::GO_MATCHING_RIGHT

Constants included from Methods::Open

Methods::Open::MODELINES

Constants included from Methods::Search

Methods::Search::SEARCH_HIGHLIGHT

Constants included from Methods::Completion

Methods::Completion::ASPELL_PARSE

Instance Attribute Summary collapse

Attributes included from Methods::Open

#options

Instance Method Summary collapse

Methods included from Methods::Views

#view_close, #view_create, #view_find_or_create, #view_focus_next, #view_focus_prev, #view_master_dec, #view_master_inc, #view_one, #view_push_bottom, #view_push_down, #view_push_top, #view_push_up, #view_slave_dec, #view_slave_inc, #view_two

Methods included from Methods::Clipboard

#copy, #copy_array, #copy_fallback, #copy_left_word, #copy_line, #copy_message, #copy_right_word, #copy_string, #paste, #paste_continous, #paste_tk_array

Methods included from Methods::Shortcuts

#wq

Methods included from Methods::Move

#backward_char, #backward_word, #beginning_of_line, #end_of_file, #end_of_line, #eol_then_insert_mode, #forward_char, #forward_char_then_insert_mode, #forward_word, #go_line, #matching_brace, #next_line, #page_down, #page_up, #previous_line, #sol_then_insert_mode, #virtual_movement, #word_right_end

Methods included from Methods::Save

#file_save, #file_save_popup, #may_close, #persisted?, #quit, #save_atomic, #save_dumb, #save_to

Methods included from Methods::Open

#after_open, #apply_modeline, #apply_modeline_option, #open_empty, #open_path, #read_file, #set, #set_filetype

Methods included from Methods::Insert

#auto_indent_line, #fallback_insert_indented_newline, #indent_after, #indent_fix_at, #indent_of, #indent_settings, #insert_auto_indented_newline, #insert_file_contents, #insert_indented_newline, #insert_indented_newline_above, #insert_indented_newline_below, #insert_newline, #insert_selection, #insert_string, #insert_tab, #syntax_indent_file

Methods included from Methods::Search

#search_char_left, #search_char_right, #search_next, #search_next_word_under_cursor, #search_prev, #search_prev_word_under_cursor, #status_search_common, #status_search_next, #status_search_prev

Methods included from Methods::Preview

#preview

Methods included from Methods::Delete

#change_line, #change_motion, #delete_line, #delete_motion, #delete_trailing_whitespace

Methods included from Methods::Ctags

#ctags_content, #ctags_execute, #ctags_find, #ctags_find_current

Methods included from Methods::Control

#buffer_switch, #clean_line, #eval_buffer, #file_open_fuzzy, #file_open_popup, #gsub, #indent_line, #join_lines, #line_evaluate, #open_console, #open_grep_list, #open_method_list, #open_terminal, #redo, #replace_char, #smart_evaluate, #start_control_mode, #start_insert_mode, #status_evaluate, #status_ex, #status_ex_filter, #status_theme_select, #stdout_capture_evaluate, #sub, #syntax_switch, #tags_at, #theme_switch, #undo, #unindent_line, #window_switch, #wrap_line

Methods included from Methods::Completion

#aspell_completions, #aspell_execute, #complete, #complete_again, #complete_aspell, #complete_file, #complete_line, #complete_tm, #complete_word, #file_completions, #line_completions, #scope_compare, #smart_tab, #tm_completions, #word_completions

Constructor Details

#initialize(view, options = {}) ⇒ Text

Returns a new instance of Text.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ver/text.rb', line 50

def initialize(view, options = {})
  super
  self.view = view

  keymap_name = VER.options.keymap
  self.keymap = Keymap.get(name: keymap_name, receiver: self)

  apply_mode_style(keymap.mode) # for startup
  setup_tags

  self.selection_start = nil
  @pristine = true
  @syntax = nil
  @options = Options.new(:text, VER.options)
  @encoding = Encoding.default_internal
  @dirty_indices = []

  self.mode = keymap.mode
end

Instance Attribute Details

#encodingObject (readonly)

Returns the value of attribute encoding.



45
46
47
# File 'lib/ver/text.rb', line 45

def encoding
  @encoding
end

#filenameObject

Returns the value of attribute filename.



45
46
47
# File 'lib/ver/text.rb', line 45

def filename
  @filename
end

#keymapObject

Returns the value of attribute keymap.



44
45
46
# File 'lib/ver/text.rb', line 44

def keymap
  @keymap
end

#pristineObject (readonly)

Returns the value of attribute pristine.



45
46
47
# File 'lib/ver/text.rb', line 45

def pristine
  @pristine
end

#selection_modeObject

attributes for diverse functionality



48
49
50
# File 'lib/ver/text.rb', line 48

def selection_mode
  @selection_mode
end

#selection_startObject

attributes for diverse functionality



48
49
50
# File 'lib/ver/text.rb', line 48

def selection_start
  @selection_start
end

#statusObject

Returns the value of attribute status.



44
45
46
# File 'lib/ver/text.rb', line 44

def status
  @status
end

#syntaxObject (readonly)

Returns the value of attribute syntax.



45
46
47
# File 'lib/ver/text.rb', line 45

def syntax
  @syntax
end

#viewObject

Returns the value of attribute view.



44
45
46
# File 'lib/ver/text.rb', line 44

def view
  @view
end

Instance Method Details

#delete(*args) ⇒ Object

fix the ruby definition of delete, Tk allows more than 2 indices



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/ver/text.rb', line 212

def delete(*args)
  if args.size > 2
    deleted = args.each_slice(2).map{|left, right| get(left, right) }
  else
    deleted = get(*args)
  end

  copy(deleted)

  execute('delete', *args)

  touch!(*args)
end

#fast_tag_add(tag, *indices) ⇒ Object



254
255
256
257
258
259
# File 'lib/ver/text.rb', line 254

def fast_tag_add(tag, *indices)
  execute('tag', 'add', tag, *indices)
  self
rescue RuntimeError => ex
  VER.error(ex)
end

#focusObject



249
250
251
252
# File 'lib/ver/text.rb', line 249

def focus
  super
  Tk::Event.generate(self, '<<Focus>>')
end

#index(idx) ⇒ Object



70
71
72
# File 'lib/ver/text.rb', line 70

def index(idx)
  Index.new(self, execute('index', idx).to_s)
end

#insert(*args) ⇒ Object



226
227
228
229
# File 'lib/ver/text.rb', line 226

def insert(*args)
  super
  touch!(args.first)
end

#layoutObject



90
91
92
# File 'lib/ver/text.rb', line 90

def layout
  view.layout
end

#mark_set(mark_name, index) ⇒ Object

Wrap Tk methods to behave as we want and to generate events



180
181
182
183
184
# File 'lib/ver/text.rb', line 180

def mark_set(mark_name, index)
  super
  return unless mark_name == :insert
  Tk::Event.generate(self, '<<Movement>>')
end

#message(*args) ⇒ Object



74
75
76
# File 'lib/ver/text.rb', line 74

def message(*args)
  status.message(*args)
end

#noop(*args) ⇒ Object



78
79
80
# File 'lib/ver/text.rb', line 78

def noop(*args)
  message "Noop %p in mode %p" % [args, keymap.mode]
end

#refresh_selectionObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/ver/text.rb', line 186

def refresh_selection
  return unless start = selection_start

  now = index(:insert)
  left, right = [start, now].sort
  tag_remove :sel, '1.0', 'end'

  case selection_mode
  when :select_char
    tag_add :sel, left, "#{right} + 1 chars"
  when :select_line
    tag_add :sel, "#{left} linestart", "#{right} lineend"
  when :select_block
    ly, lx = left.split
    ry, rx = right.split

    from_y, to_y = [ly, ry].sort
    from_x, to_x = [lx, rx].sort

    from_y.upto to_y do |y|
      tag_add :sel, "#{y}.#{from_x}", "#{y}.#{to_x + 1}"
    end
  end
end

#replace(index1, index2, *rest) ⇒ Object

Replaces the range of characters between index1 and index2 with the given characters and tags. See the section on [insert] for an explanation of the handling of the tag_list arguments, and the section on [delete] for an explanation of the handling of the indices. If index2 corresponds to an index earlier in the text than index1, an error will be generated. The deletion and insertion are arranged so that no unnecessary scrolling of the window or movement of insertion cursor occurs. In addition the undo/redo stack are correctly modified, if undo operations are active in the text widget.

replace index1 index2 chars ?tagList chars tagList …?



244
245
246
247
# File 'lib/ver/text.rb', line 244

def replace(index1, index2, *rest)
  super
  touch!(*index(index1).upto(index(index2)).to_a)
end

#rsearch_all(regexp, from = 'end', to = '1.0') ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ver/text.rb', line 159

def rsearch_all(regexp, from = 'end', to = '1.0')
  return Enumerator.new(self, :rsearch_all, regexp, from) unless block_given?

  while result = rsearch(regexp, from, to, :count)
    pos, len = result
    break if !pos || len == 0

    match = get(pos, "#{pos} + #{len} chars")
    from = index("#{pos} - #{len} chars")

    yield(match, pos, from)
  end
end

#schedule_highlight(options = {}) ⇒ Object



294
295
296
297
# File 'lib/ver/text.rb', line 294

def schedule_highlight(options = {})
  return unless @syntax
  schedule_highlight!
end

#schedule_line_highlight(raw_index) ⇒ Object



288
289
290
291
292
# File 'lib/ver/text.rb', line 288

def schedule_line_highlight(raw_index)
  return unless @syntax
  index = index(raw_index)
  schedule_line_highlight!(index.y - 1, index.linestart, index.lineend)
end

#search_all(regexp, from = '1.0', to = 'end - 1 chars') ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ver/text.rb', line 144

def search_all(regexp, from = '1.0', to = 'end - 1 chars')
  return Enumerator.new(self, :search_all, regexp, from) unless block_given?
  from, to = from.to_s, to.to_s

  while result = search(regexp, from, to, :count)
    pos, len = result
    break if !pos || len == 0

    match = get(pos, "#{pos} + #{len} chars")
    from = "#{pos} + #{len} chars"

    yield(match, pos, from)
  end
end

#set_window_titleObject



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/ver/text.rb', line 261

def set_window_title
  if filename
    home = Pathname(ENV['HOME'])
    dir, file = filename.split
    dir_relative_to_home = dir.relative_path_from(home)

    if dir_relative_to_home.to_s.start_with?('../')
      title = "#{file} (#{dir}) - VER"
    else
      title = "#{file} (#{dir_relative_to_home}) - VER"
    end
  else
    title = "[No Name] - VER"
  end

  VER.root.wm_title = title
end

#setup_highlightObject



279
280
281
282
283
284
285
286
# File 'lib/ver/text.rb', line 279

def setup_highlight
  return unless filename
  return if @encoding == Encoding::BINARY

  if @syntax = Syntax.from_filename(filename)
    defer{ syntax.highlight(self, value) }
  end
end

#short_filenameObject



82
83
84
# File 'lib/ver/text.rb', line 82

def short_filename
  filename.sub(Dir.pwd + '/', '') if filename
end

#status_projection(into) ⇒ Object

lines start from 1 end is maximum lines + 1



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

def status_projection(into)
  format = "%s  %s  %s [%s]"

  top, bot = yview

  if top < 0.5
    percent = '[top]'
  elsif bot > 99.5
    percent = '[bot]'
  else
    percent = "#{bot.to_i}%"
  end

  additional = [keymap.mode]
  syntax_name = syntax.name if syntax
  additional << syntax_name if syntax_name
  additional << @encoding

  values = [
    short_filename,
    index(:insert).idx,
    percent,
    additional.join(' | '),
  ]

  into.value = format % values
end

#tag_all_matching(name, regexp, options = {}) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ver/text.rb', line 126

def tag_all_matching(name, regexp, options = {})
  name = name.to_s
  options = TAG_ALL_MATCHING_OPTIONS.merge(options)
  from, to = options.values_at(:from, :to)

  if tag_exists?(name)
    tag_remove(name, from, to)
  else
    fg, bg = options.values_at(:foreground, :background)
    tag_configure(name, foreground: fg, background: bg)
  end

  search_all(regexp, from, to) do |match, match_from, match_to|
    name = yield(match, match_from, match_to) if block_given?
    fast_tag_add name, match_from, match_to
  end
end

#tag_exists?(given_path) ⇒ Boolean

Returns:

  • (Boolean)


173
174
175
176
177
# File 'lib/ver/text.rb', line 173

def tag_exists?(given_path)
  tag_names.include?(given_path)
rescue RuntimeError => ex
  false
end