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
|
# File 'lib/yatte/screen.rb', line 15
def refresh(context, force: false)
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
elapsed_ms = (now - @last_render_time) * 1000
unless force || @force_redraw || elapsed_ms >= THROTTLE_MS
return
end
buffer = context.buffer
cursor = context.cursor
tabs = context.tabs
git_status = context.git_status
rows, cols = @terminal.size
current_size = [rows, cols]
if @previous_size != current_size
@force_redraw = true
@previous_size = current_size
end
tab_bar_height = (tabs && tabs.length > 1) ? 1 : 0
text_rows = rows - 2 - tab_bar_height
git_gutter = git_status ? 1 : 0
gutter_width = gutter_width_for(buffer.line_count) + git_gutter
text_cols = cols - gutter_width
cursor.scroll(text_rows, text_cols)
new_lines = []
if tab_bar_height > 0
new_lines << build_tab_bar(tabs, context.active_tab_index, cols)
end
text_rows.times do |i|
file_row = i + cursor.row_offset
new_lines << if file_row >= buffer.line_count
build_empty_row(buffer, cursor, i, text_rows, cols)
else
build_text_row(buffer, file_row, cursor, gutter_width,
text_cols, cols, context.selection, context.bracket_match,
context.language, git_status)
end
end
new_lines << build_status_bar(context.filename, context.dirty,
buffer, cursor, cols)
new_lines << build_message_bar(context.message, context.message_time,
cols)
buf = +""
buf << Yatte::HIDE_CURSOR
new_lines.each_with_index do |line, i|
if @force_redraw || i >= @previous_lines.length || @previous_lines[i] != line
buf << "\x1b[#{i + 1};1H" << line << Yatte::CLEAR
end
end
position_cursor(buf, cursor, gutter_width, tab_bar_height)
buf << Yatte::SHOW_CURSOR
@terminal.write(buf)
@previous_lines = new_lines
@force_redraw = false
@last_render_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
|