git_spelunk 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/bin/git-spelunk +6 -1
- data/lib/git_spelunk/blame.rb +36 -0
- data/lib/git_spelunk/file_context.rb +9 -19
- data/lib/git_spelunk/ui.rb +110 -131
- data/lib/git_spelunk/ui/pager.rb +36 -29
- data/lib/git_spelunk/ui/repo.rb +21 -21
- data/lib/git_spelunk/ui/status.rb +11 -21
- data/lib/git_spelunk/version.rb +1 -1
- metadata +17 -3
- data/lib/git_spelunk/ui/window.rb +0 -19
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzI4MDI1MzBhYzllMTQ1N2I0YTM5ZGY0ZTVmZjUwYzI0NDE2ZTFkMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjJiZWJkMWM0MmU0OTEzMjEyMjgwNjJjNmNjZTEzMTU4NjUyMWIwMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWI4MjdiOTg0OTdiNDk0YTVhZmI2NzU1MmIyYTkxMThhMzhkOWJmOThjMDkw
|
10
|
+
MmUyMjQ0NDg2OThmMjg2NTRmZjc5YzkzMDhlZGQ4NzhmYWEyNTUyYjgyODVj
|
11
|
+
NDc3NzEwMDJjOGRiNjBkN2UxZTg4YzdmOWE0MWE0ZTYyZjJmM2Y=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OGZiMTMwMDgyYmU1YzA4ZmI4N2I0Yzc2NDA5YTYxMTA2ZjY0ZDJiNDE1NTJk
|
14
|
+
MzhlOTI4NTMwYzRhMGM1YjIxMWYxYjcyMTcwNTU5NTc0NmYxYjdhODQ0NjEy
|
15
|
+
NjQ5ZGE4YTQ4NDRhMWM5MGI3MmFmNTQ0NTcxYmJkNzIxNDZkNTU=
|
data/bin/git-spelunk
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
3
3
|
require 'git_spelunk'
|
4
|
+
require 'dispel'
|
4
5
|
require 'optparse'
|
5
6
|
|
6
7
|
def parse_options(argv)
|
@@ -31,6 +32,10 @@ file = ARGV[0]
|
|
31
32
|
file, line = file.split(':',2) if file.include?(':')
|
32
33
|
options[:line_number] = line
|
33
34
|
|
35
|
+
def log(stuff)
|
36
|
+
File.open('spelunk.log','ab'){|f| f.puts stuff }
|
37
|
+
end
|
38
|
+
|
34
39
|
file_context = GitSpelunk::FileContext.new(file, options)
|
35
40
|
ui = GitSpelunk::UI.new(file_context)
|
36
|
-
ui.run
|
41
|
+
#ui.run
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GitSpelunk
|
2
|
+
BlameLine = Struct.new(:line_number, :old_line_number, :sha, :commit, :filename, :content)
|
3
|
+
class Blame < Grit::Blame
|
4
|
+
def process_raw_blame(output)
|
5
|
+
lines, final = [], []
|
6
|
+
info, commits = {}, {}
|
7
|
+
|
8
|
+
current_filename = nil
|
9
|
+
# process the output
|
10
|
+
output.split("\n").each do |line|
|
11
|
+
if line[0, 1] == "\t"
|
12
|
+
lines << line[1, line.size]
|
13
|
+
elsif m = /^(\w{40}) (\d+) (\d+)/.match(line)
|
14
|
+
commit_id, old_lineno, lineno = m[1], m[2].to_i, m[3].to_i
|
15
|
+
commits[commit_id] = nil
|
16
|
+
info[lineno] = [commit_id, old_lineno, current_filename]
|
17
|
+
elsif line =~ /^filename (.*)/
|
18
|
+
current_filename = $1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# load all commits in single call
|
23
|
+
@repo.batch(*commits.keys).each do |commit|
|
24
|
+
commits[commit.id] = commit
|
25
|
+
end
|
26
|
+
|
27
|
+
# get it together
|
28
|
+
info.sort.each do |lineno, (commit_id, old_lineno, filename)|
|
29
|
+
commit = commits[commit_id]
|
30
|
+
final << GitSpelunk::BlameLine.new(lineno, old_lineno, commit_id, commit, filename, lines[lineno - 1])
|
31
|
+
end
|
32
|
+
@lines = final
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'grit'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'git_spelunk/blame'
|
3
4
|
|
4
5
|
module GitSpelunk
|
5
6
|
class FileContext
|
@@ -20,14 +21,13 @@ module GitSpelunk
|
|
20
21
|
@commit_cache = {}
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
new_sha
|
26
|
-
GitSpelunk::FileContext.new(@file, {:sha => new_sha, :repo => @repo, :file => @file})
|
24
|
+
def clone_for_blame_line(blame_line)
|
25
|
+
new_sha = blame_line.sha + "~1"
|
26
|
+
GitSpelunk::FileContext.new(blame_line.filename, {:sha => new_sha, :repo => @repo, :file => blame_line.filename})
|
27
27
|
end
|
28
28
|
|
29
|
-
def get_line_for_sha_parent(
|
30
|
-
o = GitSpelunk::Offset.new(@repo,
|
29
|
+
def get_line_for_sha_parent(blame_line)
|
30
|
+
o = GitSpelunk::Offset.new(@repo, blame_line.filename, blame_line.sha, blame_line.old_line_number)
|
31
31
|
o.line_number_to_parent
|
32
32
|
end
|
33
33
|
|
@@ -50,23 +50,13 @@ module GitSpelunk
|
|
50
50
|
@blame_data ||= begin
|
51
51
|
@new_to_old = {}
|
52
52
|
@line_to_sha = {}
|
53
|
-
|
54
|
-
blame.lines.map do |line|
|
55
|
-
@new_to_old[line.lineno] = line.oldlineno
|
56
|
-
[line.commit.id_abbrev, line.line]
|
57
|
-
end
|
53
|
+
GitSpelunk::Blame.new(@repo, @file, @sha).lines
|
58
54
|
end
|
59
|
-
@blame_data
|
60
|
-
end
|
61
|
-
|
62
|
-
def sha_for_line(line)
|
63
|
-
@blame_data[line - 1][0]
|
64
55
|
end
|
65
56
|
|
66
|
-
def get_line_commit_info(
|
57
|
+
def get_line_commit_info(blame_line)
|
67
58
|
get_blame
|
68
|
-
|
69
|
-
commit = (@commit_cache[abbrev] ||= @repo.commit(abbrev))
|
59
|
+
commit = blame_line.commit
|
70
60
|
return nil unless commit
|
71
61
|
|
72
62
|
author_info = commit.author_string.split(" ")
|
data/lib/git_spelunk/ui.rb
CHANGED
@@ -1,104 +1,86 @@
|
|
1
|
-
require 'git_spelunk/ui/window'
|
2
1
|
require 'git_spelunk/ui/pager'
|
3
2
|
require 'git_spelunk/ui/repo'
|
4
3
|
require 'git_spelunk/ui/status'
|
5
|
-
require 'curses'
|
6
4
|
|
7
5
|
module GitSpelunk
|
8
6
|
class UI
|
9
7
|
def initialize(file_context)
|
10
|
-
|
8
|
+
Dispel::Screen.open(:colors => true) do |screen|
|
9
|
+
calculate_heights!
|
10
|
+
@file_context = file_context
|
11
|
+
@history = [file_context]
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
@history = [file_context]
|
13
|
+
@pager = PagerWindow.new(@pager_height)
|
14
|
+
@pager.data = @file_context.get_blame
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
@repo = RepoWindow.new(@repo_height)
|
17
|
+
set_repo_content
|
18
18
|
|
19
|
-
|
19
|
+
@status = StatusWindow.new
|
20
|
+
set_status_message
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
screen.draw *draw
|
23
|
+
Dispel::Keyboard.output :timeout => 0.30 do |key|
|
24
|
+
handle_key(key)
|
25
|
+
screen.draw *draw
|
26
|
+
end
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
def draw
|
31
|
+
view1, style1 = @pager.draw
|
32
|
+
view2, style2 = @repo.draw
|
33
|
+
view3, style3 = @status.draw
|
34
|
+
|
35
|
+
cursor = if typing?
|
36
|
+
[@pager_height + @repo_height, @status.command_buffer.size + 1]
|
37
|
+
else
|
38
|
+
[Curses.lines-1, Curses.cols]
|
39
|
+
end
|
40
|
+
|
41
|
+
[
|
42
|
+
[view1, view2, view3].join("\n"),
|
43
|
+
style1 + style2 + style3,
|
44
|
+
cursor
|
45
|
+
]
|
36
46
|
end
|
37
47
|
|
38
48
|
def calculate_heights!
|
39
|
-
@repo_height = [(Curses.lines.to_f * 0.20).to_i, 6].max
|
40
|
-
@pager_height = Curses.lines - @repo_height - 1
|
41
49
|
@status_height = 1
|
42
|
-
|
43
|
-
|
44
|
-
def run
|
45
|
-
@repo.content = @file_context.get_line_commit_info(@pager.cursor)
|
46
|
-
pause_thread
|
47
|
-
begin
|
48
|
-
[@pager, @repo, @status].each(&:draw)
|
49
|
-
handle_key(Curses.getch)
|
50
|
-
end while true
|
50
|
+
@repo_height = [(Curses.lines.to_f * 0.20).to_i, 6].max
|
51
|
+
@pager_height = Curses.lines - @repo_height - @status_height
|
51
52
|
end
|
52
53
|
|
53
54
|
def set_status_message
|
54
55
|
@status.status_message = "#{@file_context.file} @ #{@file_context.sha}"
|
55
56
|
end
|
56
57
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
while true
|
61
|
-
if heartbeat_expired? && @last_line != @pager.cursor
|
62
|
-
current_line = @pager.cursor
|
63
|
-
content = @file_context.get_line_commit_info(current_line)
|
64
|
-
if heartbeat_expired? && @pager.cursor == current_line
|
65
|
-
@repo.content = content
|
66
|
-
@repo.draw
|
67
|
-
@last_line = current_line
|
68
|
-
else
|
69
|
-
@heartbeat = Time.now
|
70
|
-
end
|
71
|
-
end
|
72
|
-
sleep 0.05
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def heartbeat_expired?
|
78
|
-
@heartbeat && (Time.now - @heartbeat).to_f > 0.30
|
58
|
+
def set_repo_content
|
59
|
+
@repo.content = @file_context.get_line_commit_info(@pager.blame_line)
|
60
|
+
@repo.draw
|
79
61
|
end
|
80
62
|
|
81
63
|
def after_navigation
|
82
64
|
@pager.highlight_sha = true
|
65
|
+
set_repo_content
|
83
66
|
@status.exit_command_mode!
|
84
67
|
@status.clear_onetime_message!
|
85
68
|
end
|
86
69
|
|
87
70
|
def history_back
|
88
71
|
@status.set_onetime_message("Rewinding...")
|
89
|
-
goto = @file_context.get_line_for_sha_parent(@pager.
|
72
|
+
goto = @file_context.get_line_for_sha_parent(@pager.blame_line)
|
90
73
|
if goto.is_a?(Fixnum)
|
91
74
|
@file_context.line_number = @pager.cursor
|
92
75
|
@history.push(@file_context)
|
93
76
|
|
94
|
-
@file_context = @file_context.
|
77
|
+
@file_context = @file_context.clone_for_blame_line(@pager.blame_line)
|
95
78
|
@pager.data = @file_context.get_blame
|
96
79
|
@pager.go_to(goto)
|
97
80
|
|
98
|
-
|
81
|
+
set_repo_content
|
99
82
|
@status.clear_onetime_message!
|
100
83
|
set_status_message
|
101
|
-
@last_line = nil
|
102
84
|
elsif goto == :at_beginning_of_time
|
103
85
|
@status.set_onetime_message("At beginning of repository history!")
|
104
86
|
elsif goto == :unable_to_trace
|
@@ -113,97 +95,94 @@ module GitSpelunk
|
|
113
95
|
@file_context = @history.pop
|
114
96
|
@pager.data = @file_context.get_blame
|
115
97
|
@pager.go_to(@file_context.line_number)
|
98
|
+
set_repo_content
|
116
99
|
|
117
100
|
@status.clear_onetime_message!
|
118
101
|
set_status_message
|
119
|
-
|
120
|
-
# force commit info update
|
121
|
-
@last_line = nil
|
122
102
|
end
|
123
103
|
end
|
124
104
|
|
125
105
|
def handle_key(key)
|
126
|
-
@heartbeat = Time.now
|
127
106
|
case key
|
128
|
-
when
|
129
|
-
@pager.cursordown
|
130
|
-
after_navigation
|
131
|
-
when Curses::KEY_UP, '-', 'k'
|
132
|
-
@pager.cursorup
|
133
|
-
after_navigation
|
134
|
-
when Curses::KEY_CTRL_D, ' '
|
107
|
+
when :"Ctrl+d", ' ', :page_down
|
135
108
|
@pager.pagedown
|
136
109
|
after_navigation
|
137
|
-
when
|
110
|
+
when :"Ctrl+u", :page_up
|
138
111
|
@pager.pageup
|
139
112
|
after_navigation
|
140
|
-
when
|
141
|
-
@status.command_buffer += key
|
142
|
-
when Curses::KEY_CTRL_M
|
143
|
-
if @status.command_buffer != ''
|
144
|
-
@pager.go_to(@status.command_buffer.to_i)
|
145
|
-
end
|
146
|
-
after_navigation
|
147
|
-
when 'G'
|
148
|
-
if @status.command_buffer != ''
|
149
|
-
@pager.go_to(@status.command_buffer.to_i)
|
150
|
-
else
|
151
|
-
@pager.go_bottom
|
152
|
-
end
|
153
|
-
after_navigation
|
154
|
-
when '['
|
155
|
-
history_back
|
156
|
-
when ']'
|
157
|
-
history_forward
|
158
|
-
when 's'
|
159
|
-
@heartbeat = nil
|
160
|
-
sha = @file_context.sha_for_line(@pager.cursor)
|
161
|
-
Curses.close_screen
|
162
|
-
system("git -p --git-dir='#{@file_context.repo.path}' show #{sha} | less")
|
163
|
-
Curses.stdscr.refresh
|
164
|
-
when '/', '?'
|
165
|
-
@heartbeat = nil
|
166
|
-
@status.command_buffer = key
|
167
|
-
@status.draw
|
168
|
-
|
169
|
-
line = getline
|
170
|
-
if line
|
171
|
-
@pager.search(line, false, key == '?')
|
172
|
-
end
|
173
|
-
@status.exit_command_mode!
|
174
|
-
when 'n'
|
175
|
-
@pager.search(nil, true, false)
|
176
|
-
after_navigation
|
177
|
-
when 'N'
|
178
|
-
@pager.search(nil, true, true)
|
179
|
-
after_navigation
|
180
|
-
when 'q', Curses::KEY_CTRL_C
|
113
|
+
when :"Ctrl+c"
|
181
114
|
exit
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
115
|
+
when :escape
|
116
|
+
@pager.search_term = nil
|
117
|
+
@status.exit_command_mode!
|
118
|
+
@typing = false
|
119
|
+
else
|
120
|
+
if typing?
|
121
|
+
case key
|
122
|
+
when String
|
123
|
+
if key == "G" && @typing == :goto
|
124
|
+
execute_goto
|
125
|
+
else
|
126
|
+
@status.command_buffer << key
|
127
|
+
end
|
128
|
+
when :backspace then @status.command_buffer[-1..-1] = ""
|
129
|
+
when :enter
|
130
|
+
if @typing == :search
|
131
|
+
typed = @status.command_buffer
|
132
|
+
@pager.search(typed[1..-1], false, typed[0] == '?')
|
133
|
+
elsif @typing == :goto
|
134
|
+
execute_goto
|
135
|
+
end
|
136
|
+
@typing = false
|
137
|
+
@status.command_buffer = ""
|
197
138
|
end
|
198
|
-
@status.command_buffer.chop!
|
199
139
|
else
|
200
|
-
|
201
|
-
|
140
|
+
case key
|
141
|
+
when :down, 'j'
|
142
|
+
@pager.cursordown
|
143
|
+
after_navigation
|
144
|
+
when :up, '-', 'k'
|
145
|
+
@pager.cursorup
|
146
|
+
after_navigation
|
147
|
+
when *(0..9).to_a.map(&:to_s)
|
148
|
+
@status.command_buffer = key
|
149
|
+
@typing = :goto
|
150
|
+
when '['
|
151
|
+
history_back
|
152
|
+
when ']'
|
153
|
+
history_forward
|
154
|
+
when 's'
|
155
|
+
sha = @pager.blame_line.sha
|
156
|
+
Curses.close_screen
|
157
|
+
system("git -p --git-dir='#{@file_context.repo.path}' show #{sha} | less")
|
158
|
+
when '/', '?'
|
159
|
+
@status.command_buffer = key
|
160
|
+
@typing = :search
|
161
|
+
when 'n'
|
162
|
+
@pager.search(nil, true, false)
|
163
|
+
after_navigation
|
164
|
+
when 'N'
|
165
|
+
@pager.search(nil, true, true)
|
166
|
+
after_navigation
|
167
|
+
when 'q'
|
168
|
+
exit
|
202
169
|
end
|
203
170
|
end
|
204
|
-
@status.draw
|
205
171
|
end
|
206
172
|
end
|
173
|
+
|
174
|
+
def typing?
|
175
|
+
@status.command_buffer.size > 0
|
176
|
+
end
|
177
|
+
|
178
|
+
def execute_goto
|
179
|
+
if @status.command_buffer != ''
|
180
|
+
@pager.go_to(@status.command_buffer.to_i)
|
181
|
+
else
|
182
|
+
@pager.go_bottom
|
183
|
+
end
|
184
|
+
after_navigation
|
185
|
+
end
|
207
186
|
end
|
208
187
|
end
|
209
188
|
|
data/lib/git_spelunk/ui/pager.rb
CHANGED
@@ -3,56 +3,64 @@ require 'curses'
|
|
3
3
|
ACTIVE_SHA_COLOR=1
|
4
4
|
module GitSpelunk
|
5
5
|
class UI
|
6
|
-
class PagerWindow
|
6
|
+
class PagerWindow
|
7
|
+
ACTIVE_SHA_COLOR = ["#00ff00", "#000000"]
|
8
|
+
FOUND_COLOR = :reverse
|
9
|
+
CURRENT_COLOR = ["#000000", "#00ff00"]
|
10
|
+
|
7
11
|
def initialize(height)
|
8
|
-
@window = Curses::Window.new(height, Curses.cols, 0, 0)
|
9
12
|
@height = height
|
10
13
|
@cursor = 1
|
11
14
|
@top = 1
|
12
15
|
@highlight_sha = true
|
13
16
|
end
|
14
17
|
|
15
|
-
attr_accessor :data, :highlight_sha
|
16
|
-
attr_reader :cursor, :top
|
18
|
+
attr_accessor :data, :highlight_sha, :search_term
|
19
|
+
attr_reader :cursor, :top, :data
|
20
|
+
|
21
|
+
def blame_line
|
22
|
+
@data[@cursor - 1]
|
23
|
+
end
|
17
24
|
|
18
25
|
def draw
|
19
|
-
@
|
20
|
-
|
26
|
+
styles = Dispel::StyleMap.new(@height)
|
27
|
+
|
21
28
|
line_number_width = (data.size + 1).to_s.size
|
22
29
|
|
23
|
-
active_sha =
|
30
|
+
active_sha = blame_line.sha
|
31
|
+
|
32
|
+
view = Array.new(@height)
|
33
|
+
|
34
|
+
data[@top - 1,@height].each_with_index.map do |b, i|
|
35
|
+
line = view[i] = ""
|
36
|
+
sha, content = b.sha, b.content
|
24
37
|
|
25
|
-
data[@top - 1,@height].each_with_index do |b, i|
|
26
|
-
sha, content = *b
|
27
38
|
line_number = i + @top
|
39
|
+
content_start = (sha.size + line_number_width + 2)
|
28
40
|
|
29
41
|
if sha == active_sha && highlight_sha
|
30
|
-
|
42
|
+
styles.add(ACTIVE_SHA_COLOR, i, 0...999)
|
31
43
|
end
|
32
44
|
|
45
|
+
sha_abbrev = sha[0..5]
|
33
46
|
if @cursor == line_number
|
34
|
-
|
35
|
-
else
|
36
|
-
@window.addstr(sha)
|
47
|
+
styles.add(CURRENT_COLOR, i, 0..(sha_abbrev.size - 1))
|
37
48
|
end
|
38
49
|
|
39
|
-
|
50
|
+
line << sha_abbrev
|
51
|
+
|
52
|
+
line << " %*s " % [line_number_width, line_number]
|
53
|
+
line << content
|
54
|
+
|
40
55
|
if @search_term
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
@window.addstr(t[0,line_remainder])
|
46
|
-
@window.attroff(Curses::A_STANDOUT)
|
56
|
+
Dispel::Tools.indexes(content, @search_term).each do |found|
|
57
|
+
found = content_start + found
|
58
|
+
styles.add(FOUND_COLOR, i, found...(found + @search_term.size))
|
47
59
|
end
|
48
|
-
else
|
49
|
-
@window.addstr(content[0,line_remainder])
|
50
60
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@window.refresh
|
55
|
-
@window.setpos(0,0)
|
61
|
+
end.join("\n")
|
62
|
+
|
63
|
+
[view, styles]
|
56
64
|
end
|
57
65
|
|
58
66
|
attr_accessor :top
|
@@ -61,7 +69,7 @@ module GitSpelunk
|
|
61
69
|
def find_next_index(term, start, reverse)
|
62
70
|
i = start
|
63
71
|
while i < data.size && i >= 0
|
64
|
-
if data[i]
|
72
|
+
if data[i].content =~ /#{term}/
|
65
73
|
return i
|
66
74
|
end
|
67
75
|
i += reverse ? -1 : 1
|
@@ -142,7 +150,6 @@ module GitSpelunk
|
|
142
150
|
adjust_top!
|
143
151
|
end
|
144
152
|
|
145
|
-
|
146
153
|
def go_bottom
|
147
154
|
@cursor = data.size
|
148
155
|
@top = data.size - (@height - 1)
|
data/lib/git_spelunk/ui/repo.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
module GitSpelunk
|
2
2
|
class UI
|
3
|
-
class RepoWindow
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class RepoWindow
|
4
|
+
attr_accessor :content, :command_mode, :command_buffer
|
5
|
+
|
6
|
+
def initialize(height)
|
7
7
|
@height = height
|
8
|
-
|
8
|
+
self.content = ""
|
9
9
|
end
|
10
10
|
|
11
|
-
attr_accessor :content, :command_mode, :command_buffer
|
12
|
-
|
13
11
|
def draw
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
styles = Dispel::StyleMap.new(@height)
|
13
|
+
styles.add(:reverse, 0, 0..999)
|
14
|
+
view = [status_line] + content.split("\n")
|
15
|
+
view = Array.new(@height).each_with_index.map {|_,i| view[i] }
|
16
|
+
[view, styles]
|
19
17
|
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
private
|
20
|
+
|
21
|
+
#with_highlighting do
|
22
|
+
def status_line
|
23
|
+
[
|
24
|
+
"navigation: j k CTRL-D CTRL-U",
|
25
|
+
"history: [ ]",
|
26
|
+
"search: / ? n N",
|
27
|
+
"git-show: s",
|
28
|
+
"quit: q"
|
29
|
+
].join(" ")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module GitSpelunk
|
2
2
|
class UI
|
3
|
-
class StatusWindow
|
4
|
-
def initialize
|
5
|
-
@window = Curses::Window.new(height, Curses.cols, offset, 0)
|
6
|
-
@offset = offset
|
3
|
+
class StatusWindow
|
4
|
+
def initialize
|
7
5
|
@command_buffer = ""
|
8
6
|
@status_message = ""
|
9
7
|
@onetime_message = nil
|
@@ -17,32 +15,24 @@ module GitSpelunk
|
|
17
15
|
|
18
16
|
def set_onetime_message(message)
|
19
17
|
@onetime_message = message
|
20
|
-
draw
|
21
18
|
end
|
22
19
|
|
23
20
|
def exit_command_mode!
|
24
21
|
self.command_buffer = ""
|
25
22
|
end
|
26
23
|
|
27
|
-
def set_cursor
|
28
|
-
Curses::stdscr.setpos(@offset, command_buffer.size + 1)
|
29
|
-
end
|
30
|
-
|
31
24
|
def draw
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@window.addstr(" " * line_remainder)
|
25
|
+
styles = Dispel::StyleMap.new(1)
|
26
|
+
|
27
|
+
view = if command_buffer.size > 0
|
28
|
+
":" + command_buffer
|
37
29
|
else
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@window.addstr(" " * line_remainder + "\n")
|
42
|
-
end
|
30
|
+
message = (@onetime_message || @status_message)
|
31
|
+
styles.add(:reverse, 0, 0...999)
|
32
|
+
message
|
43
33
|
end
|
44
|
-
|
45
|
-
|
34
|
+
|
35
|
+
[view, styles]
|
46
36
|
end
|
47
37
|
end
|
48
38
|
end
|
data/lib/git_spelunk/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_spelunk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Osheroff
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grit
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - ! '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: dispel
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
description: git-spelunk is a terminal based exploration tool for git blame and history,
|
29
43
|
based on the notion of moving in history based on file context
|
30
44
|
email:
|
@@ -38,6 +52,7 @@ files:
|
|
38
52
|
- MIT-LICENSE.txt
|
39
53
|
- bin/git-spelunk
|
40
54
|
- lib/git_spelunk.rb
|
55
|
+
- lib/git_spelunk/blame.rb
|
41
56
|
- lib/git_spelunk/file_context.rb
|
42
57
|
- lib/git_spelunk/grit_patches.rb
|
43
58
|
- lib/git_spelunk/offset.rb
|
@@ -45,7 +60,6 @@ files:
|
|
45
60
|
- lib/git_spelunk/ui/pager.rb
|
46
61
|
- lib/git_spelunk/ui/repo.rb
|
47
62
|
- lib/git_spelunk/ui/status.rb
|
48
|
-
- lib/git_spelunk/ui/window.rb
|
49
63
|
- lib/git_spelunk/version.rb
|
50
64
|
homepage: https://github.com/osheroff/git-spelunk
|
51
65
|
licenses:
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'curses'
|
2
|
-
|
3
|
-
module GitSpelunk
|
4
|
-
class UI
|
5
|
-
class Window
|
6
|
-
def with_highlighting
|
7
|
-
@window.attron(Curses::A_STANDOUT)
|
8
|
-
yield
|
9
|
-
ensure
|
10
|
-
@window.attroff(Curses::A_STANDOUT)
|
11
|
-
end
|
12
|
-
|
13
|
-
def line_remainder
|
14
|
-
Curses.cols - @window.curx - 1
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|