nit 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/README.md +205 -15
- data/Rakefile +11 -0
- data/Thorfile +19 -0
- data/bin/nit +4 -0
- data/lib/nit/CHANGES.mk +7 -0
- data/lib/nit/app.rb +80 -0
- data/lib/nit/commit.rb +7 -0
- data/lib/nit/config.rb +81 -0
- data/lib/nit/files.rb +60 -0
- data/lib/nit/ignore.rb +36 -0
- data/lib/nit/lines.rb +63 -0
- data/lib/nit/status.rb +94 -0
- data/lib/nit/version.rb +1 -1
- data/lib/nit.rb +0 -3
- data/nit.gemspec +6 -3
- data/test/config_test.rb +15 -0
- data/test/dummies/stage/.gitignore +1 -0
- data/test/dummies/stage/brandnew.rb +0 -0
- data/test/dummies/stage/git/COMMIT_EDITMSG +21 -0
- data/test/dummies/stage/git/HEAD +1 -0
- data/test/dummies/stage/git/config +5 -0
- data/test/dummies/stage/git/description +1 -0
- data/test/dummies/stage/git/hooks/applypatch-msg.sample +15 -0
- data/test/dummies/stage/git/hooks/commit-msg.sample +24 -0
- data/test/dummies/stage/git/hooks/post-update.sample +8 -0
- data/test/dummies/stage/git/hooks/pre-applypatch.sample +14 -0
- data/test/dummies/stage/git/hooks/pre-commit.sample +50 -0
- data/test/dummies/stage/git/hooks/pre-rebase.sample +169 -0
- data/test/dummies/stage/git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummies/stage/git/hooks/update.sample +128 -0
- data/test/dummies/stage/git/index +0 -0
- data/test/dummies/stage/git/info/exclude +6 -0
- data/test/dummies/stage/git/logs/HEAD +2 -0
- data/test/dummies/stage/git/logs/refs/heads/master +2 -0
- data/test/dummies/stage/git/objects/0f/e4f83176db6842cd95f439f1edad3cb8483b4e +0 -0
- data/test/dummies/stage/git/objects/5c/0d92dd14afeb4c2bcd11bc3f072390be598a73 +1 -0
- data/test/dummies/stage/git/objects/60/bd895ee4a908b754f1980491c0e0852c29a8cd +0 -0
- data/test/dummies/stage/git/objects/b7/5ac79d08245a3a8a662520dd90f80be097cc44 +1 -0
- data/test/dummies/stage/git/objects/c1/172bf75d73a630c467f1e1448c44d9188fe23e +0 -0
- data/test/dummies/stage/git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
- data/test/dummies/stage/git/refs/heads/master +1 -0
- data/test/dummies/stage/new.rb +0 -0
- data/test/dummies/stage/on_stage.rb +1 -0
- data/test/dummies/stage/staged.rb +1 -0
- data/test/files_test.rb +45 -0
- data/test/ignore_test.rb +46 -0
- data/test/lines_test.rb +26 -0
- data/test/nit_test.rb +48 -0
- data/test/status_test.rb +88 -0
- data/test/test_helper.rb +2 -0
- metadata +122 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 553741b0650ad5eba01775f8cda663d3aedf8ca0
|
4
|
+
data.tar.gz: 9041785b1191731540185990574b2dc3bb3978a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff8ad770fa0d4022b6712c890128d420e23bb0cefa50445e77a3bf9b895178822e308433ba955de777925d98f475e059e0b26944dff9f7d26074ae60855696d7
|
7
|
+
data.tar.gz: 0aa20962038881633ce12558f12a0025b5377ed313fa539ca59992a8105320239ffa427730e8e587d3b067847556fdf4735d30aac1a052fc16fc8827527a64e1
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,219 @@
|
|
1
1
|
# Nit
|
2
2
|
|
3
|
-
|
3
|
+
_Improving your Git workflow since 2013._
|
4
|
+
|
5
|
+
Nit is a thin command-line wrapper for git. It gives you handy shortcuts for your everyday work with git, reduces your typing and is easily extendable with your own commands.
|
6
|
+
|
4
7
|
|
5
8
|
## Installation
|
6
9
|
|
7
|
-
|
10
|
+
```
|
11
|
+
gem install nit
|
12
|
+
```
|
13
|
+
|
14
|
+
This will install the `nit` shell command.
|
15
|
+
|
16
|
+
|
17
|
+
## Status
|
18
|
+
|
19
|
+
The blank `nit` command will be your best friend.
|
20
|
+
|
21
|
+
```shell
|
22
|
+
nit
|
23
|
+
```
|
24
|
+
|
25
|
+
It's a `git status` on LSD.
|
26
|
+
|
27
|
+
```shell
|
28
|
+
# On branch master
|
29
|
+
# Changes not staged for commit:
|
30
|
+
# (use "git add <file>..." to update what will be committed)
|
31
|
+
# (use "git checkout -- <file>..." to discard changes in working directory)
|
32
|
+
#
|
33
|
+
# modified: on_stage.rb [a]
|
34
|
+
# modified: staged.rb [b]
|
35
|
+
#
|
36
|
+
# Untracked files:
|
37
|
+
# (use "git add <file>..." to include in what will be committed)
|
38
|
+
#
|
39
|
+
# brandnew.rb [c]
|
40
|
+
# new.rb [d]
|
41
|
+
```
|
42
|
+
|
43
|
+
First of all, it shows you the current branch in bold.
|
44
|
+
|
45
|
+
## File Indexes
|
46
|
+
|
47
|
+
Secondly, the status screen renders a file index for each file which can be used on the command-line.
|
48
|
+
|
49
|
+
Indexes per default are characters on the right-hand side of the filename. This can be configured, in case you prefer digits. You can also have the indexes prepended to the filename.
|
50
|
+
|
51
|
+
However, scientific studies with `nit` over the last 18 years have proven that characters instead of digits are faster to reach when typing. Also, indexes _appended_ to the filename make them easier to read when deciding what to commit.
|
52
|
+
|
53
|
+
## Commit
|
54
|
+
|
55
|
+
To commit files, you no longer use the filename but their indexes.
|
56
|
+
|
57
|
+
```shell
|
58
|
+
nit commit a c
|
59
|
+
```
|
60
|
+
|
61
|
+
Which will run
|
62
|
+
|
63
|
+
```
|
64
|
+
git add on_stage.rb
|
65
|
+
git add brandnew.rb
|
66
|
+
git commit
|
67
|
+
```
|
68
|
+
|
69
|
+
Note that nits adds and commits an already staged file _and_ an untracked file in the same step.
|
70
|
+
|
71
|
+
This could also be run as
|
72
|
+
|
73
|
+
```shell
|
74
|
+
nit commit ac
|
75
|
+
```
|
76
|
+
|
77
|
+
Nit will extract the correct indexes.
|
78
|
+
|
79
|
+
|
80
|
+
## Auto-Expansion Of Commands
|
81
|
+
|
82
|
+
You don't have to type `nit commit` everytime. Use a short-cut, nit figures out what command you want. This command will work, too.
|
83
|
+
|
84
|
+
```shell
|
85
|
+
nit co abc
|
86
|
+
```
|
87
|
+
|
88
|
+
## Add
|
89
|
+
|
90
|
+
Adding with nit becomes obsolete. It is handled by the `commit` command.
|
91
|
+
|
92
|
+
|
93
|
+
## Ignoring Files
|
94
|
+
|
95
|
+
When files on the status screen get in your way you can _ignore_ them. Nit will simply not consider them anymore until you `unignore` them.
|
96
|
+
|
97
|
+
Ignoring files is roughly equivalent to `git stash`. However, instead of having to remember dozens of stashes, you simply tell nit to hide files from your status. That helps focusing on the files you are actually working on. Trust us.
|
98
|
+
|
99
|
+
|
100
|
+
```shell
|
101
|
+
nit ignore a d
|
102
|
+
```
|
103
|
+
|
104
|
+
This tells nit to ignore `on_stage.rb` and `new.rb`.
|
105
|
+
|
106
|
+
```shell
|
107
|
+
$ nit
|
108
|
+
|
109
|
+
# On branch master
|
110
|
+
# Changes not staged for commit:
|
111
|
+
# (use "git add <file>..." to update what will be committed)
|
112
|
+
# (use "git checkout -- <file>..." to discard changes in working directory)
|
113
|
+
#
|
114
|
+
# modified: staged.rb [a]
|
115
|
+
#
|
116
|
+
# Untracked files:
|
117
|
+
# (use "git add <file>..." to include in what will be committed)
|
118
|
+
#
|
119
|
+
# brandnew.rb [b]
|
120
|
+
#
|
121
|
+
# Ignored files: 2
|
122
|
+
```
|
123
|
+
|
124
|
+
The ignored files are now longer visible. However, the last line reminds you that there are files ignored.
|
125
|
+
|
126
|
+
To get a list of ignored files, run:
|
127
|
+
|
128
|
+
```shell
|
129
|
+
nit ignore
|
130
|
+
```
|
131
|
+
|
132
|
+
```shell
|
133
|
+
[a] on_stage.rb
|
134
|
+
[b] new.rb
|
135
|
+
```
|
136
|
+
|
137
|
+
If you want to commit to the ignored files, just unignore them, again.
|
138
|
+
|
139
|
+
```shell
|
140
|
+
nit unignore a
|
141
|
+
```
|
142
|
+
|
143
|
+
## Push
|
144
|
+
|
145
|
+
To push your changes, run the following command.
|
146
|
+
|
147
|
+
```shell
|
148
|
+
nit push
|
149
|
+
```
|
150
|
+
|
151
|
+
Will figure out the current branch and run
|
152
|
+
|
153
|
+
```shell
|
154
|
+
git push origin <current branch>
|
155
|
+
```
|
156
|
+
|
157
|
+
## Pull
|
158
|
+
|
159
|
+
The same works for `nit pull`.
|
160
|
+
|
161
|
+
|
162
|
+
## Arbitrary Commands
|
163
|
+
|
164
|
+
You can use nit's index interpolation for any git command.
|
165
|
+
|
166
|
+
```shell
|
167
|
+
nit diff ab
|
168
|
+
``
|
169
|
+
|
170
|
+
|
171
|
+
## Manual Configuration
|
172
|
+
|
173
|
+
Some operations require nit to save application state. This is done in the `.nit` YAML file in your working directory. You can manually edit it.
|
174
|
+
|
175
|
+
|
176
|
+
## Alternative Indexing
|
177
|
+
|
178
|
+
You can have number-based indexing.
|
179
|
+
|
180
|
+
```shell
|
181
|
+
modified: on_stage.rb [0]
|
182
|
+
modified: staged.rb [1]
|
183
|
+
```
|
184
|
+
|
185
|
+
In `.nit`, do
|
186
|
+
|
187
|
+
```yaml
|
188
|
+
indexer = "IntegerIndexer"
|
189
|
+
```
|
190
|
+
|
191
|
+
Some people prefer the index prepending the file name.
|
192
|
+
|
193
|
+
```shell
|
194
|
+
modified: [0] on_stage.rb
|
195
|
+
modified: [1] staged.rb
|
196
|
+
|
197
|
+
```
|
198
|
+
|
199
|
+
Nap in the park.
|
200
|
+
|
201
|
+
```yaml
|
202
|
+
index_renderer = "PrependIndexRenderer"
|
203
|
+
```
|
8
204
|
|
9
|
-
|
205
|
+
## Extending Nit
|
10
206
|
|
11
|
-
|
207
|
+
Extending nit with your own commands can be done either with gems or by placing the extensions into your `.nit` directory. This will be implemented and documented soon.
|
12
208
|
|
13
|
-
$ bundle
|
14
209
|
|
15
|
-
|
210
|
+
## More
|
16
211
|
|
17
|
-
|
212
|
+
There are plenty of more features planned for the upcoming versions.
|
18
213
|
|
19
|
-
## Usage
|
20
214
|
|
21
|
-
|
215
|
+
## License
|
22
216
|
|
23
|
-
|
217
|
+
Copyright (c) 2013, Nick Sutterer <apotonick@gmail.com>
|
24
218
|
|
25
|
-
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
219
|
+
Released under the MIT License.
|
data/Rakefile
CHANGED
@@ -1 +1,12 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
desc 'Test the nit gem.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
Rake::TestTask.new(:test) do |test|
|
9
|
+
test.libs << 'test'
|
10
|
+
test.test_files = FileList["test/status_test.rb"] + FileList['test/*_test.rb']
|
11
|
+
test.verbose = true
|
12
|
+
end
|
data/Thorfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
require 'thor/rake_compat'
|
5
|
+
|
6
|
+
class Default < Thor
|
7
|
+
include Thor::RakeCompat
|
8
|
+
Bundler::GemHelper.install_tasks
|
9
|
+
|
10
|
+
desc "build", "Build nit-#{Nit::VERSION}.gem into the pkg directory"
|
11
|
+
def build
|
12
|
+
Rake::Task["build"].execute
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "install", "Build and install nit-#{Nit::VERSION}.gem into system gems"
|
16
|
+
def install
|
17
|
+
Rake::Task["install"].execute
|
18
|
+
end
|
19
|
+
end
|
data/bin/nit
ADDED
data/lib/nit/CHANGES.mk
ADDED
data/lib/nit/app.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "nit/files"
|
3
|
+
require "nit/lines"
|
4
|
+
require "nit/status"
|
5
|
+
require "nit/commit"
|
6
|
+
require "nit/config"
|
7
|
+
require "nit/ignore"
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
# TODO:
|
12
|
+
# * diff workflow: going through changed files, adding them while reading!
|
13
|
+
# * nit unstage => git reset HEAD
|
14
|
+
# * nit ignore (save time and last changed!)
|
15
|
+
# * nit unignore
|
16
|
+
# * nit co -a => git commit -a
|
17
|
+
# * nit co 1<tab> => filename
|
18
|
+
|
19
|
+
module Nit
|
20
|
+
class App < Thor
|
21
|
+
include Actions
|
22
|
+
|
23
|
+
default_command(:status)
|
24
|
+
|
25
|
+
desc "status", "bla"
|
26
|
+
def status
|
27
|
+
puts Status.new(config).call
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "commit", "blubb"
|
31
|
+
def commit(*args)
|
32
|
+
puts Commit.new(config).call(`git status`, args)
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "ignore", "blubb"
|
36
|
+
def ignore(*args)
|
37
|
+
puts Ignore.new(config).call(`git status`, args)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "unignore", "blubb"
|
41
|
+
def unignore(*args)
|
42
|
+
puts Unignore.new(config).call(`git status`, args)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
desc "pull", "pull from current branch at origin"
|
47
|
+
def pull
|
48
|
+
`git pull origin #{current_branch}`
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "push", "push to current branch at origin"
|
52
|
+
def push
|
53
|
+
`git push origin #{current_branch}`
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def current_branch
|
58
|
+
output = `git branch`
|
59
|
+
branch = output.match(/\* (.+)/)[1].strip
|
60
|
+
end
|
61
|
+
|
62
|
+
def config
|
63
|
+
@config ||= Config.new # TODO: eventually pass path.
|
64
|
+
end
|
65
|
+
|
66
|
+
# def self.dynamic_command_class
|
67
|
+
# DynamicCommand
|
68
|
+
# end
|
69
|
+
|
70
|
+
#class DynamicCommand < Thor::DynamicCommand
|
71
|
+
Thor::DynamicCommand.class_eval do # see https://github.com/erikhuda/thor/pull/358
|
72
|
+
def run(app, indexes)
|
73
|
+
command = self.name
|
74
|
+
state = Status::State.new(`git status`, app.send(:config))
|
75
|
+
|
76
|
+
puts `git #{command} #{state.files.list(indexes)}`
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/nit/commit.rb
ADDED
data/lib/nit/config.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require "psych"
|
2
|
+
require "thor"
|
3
|
+
|
4
|
+
module Nit
|
5
|
+
class Config < Thor::Group # we have to derive from Group to get the create_file working - that's messy.
|
6
|
+
include Thor::Actions
|
7
|
+
# Warning: this API will soon change.
|
8
|
+
|
9
|
+
class File
|
10
|
+
def initialize(name, app) # FIXME: i hate the app dependency for #create_file.
|
11
|
+
@name = name
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(key)
|
16
|
+
return unless exist?
|
17
|
+
yaml_hash[key]
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(key, value)
|
21
|
+
@app.create_file(@name, Psych.dump({})) unless exist?
|
22
|
+
|
23
|
+
hash = yaml_hash
|
24
|
+
hash[key] = value
|
25
|
+
::File.open(@name, "w") { |f| f.write(Psych.dump(hash)) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def rm!
|
29
|
+
@app.remove_file(@name)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def exist?
|
34
|
+
::File.exist?(@name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def yaml_hash
|
38
|
+
Psych.load_file(@name) || {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
super
|
45
|
+
@file = File.new(filename, self) # FIXME: remove the Thor::App dependency, see above!
|
46
|
+
end
|
47
|
+
|
48
|
+
def ignored_files
|
49
|
+
file.read("ignored_files") or []
|
50
|
+
end
|
51
|
+
|
52
|
+
def ignored_files=(files)
|
53
|
+
file.write("ignored_files", files.collect(&:to_s))
|
54
|
+
end
|
55
|
+
|
56
|
+
def indexer
|
57
|
+
const = file.read("indexer") || "CharIndexer"
|
58
|
+
Nit::Files.const_get(const)
|
59
|
+
end
|
60
|
+
|
61
|
+
def indexer=(value)
|
62
|
+
file.write("indexer", value)
|
63
|
+
end
|
64
|
+
|
65
|
+
def index_renderer
|
66
|
+
const = file.read("index_renderer") || "AppendIndexRenderer"
|
67
|
+
Nit::Status.const_get(const)
|
68
|
+
end
|
69
|
+
|
70
|
+
def index_renderer=(value)
|
71
|
+
file.write("index_renderer", value)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
attr_reader :file
|
76
|
+
|
77
|
+
def filename
|
78
|
+
".nit"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/nit/files.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Nit
|
2
|
+
class Files < Array
|
3
|
+
def initialize(arr=[], indexer=IntegerIndexer)
|
4
|
+
super(arr)
|
5
|
+
extend indexer
|
6
|
+
end
|
7
|
+
|
8
|
+
# we could also use a dedicated object here.
|
9
|
+
module PublicMethods
|
10
|
+
def [](index)
|
11
|
+
super(index.to_i)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return list of file names for indexes.
|
15
|
+
def evaluate(indexes)
|
16
|
+
indexes.collect { |i| self[i] }
|
17
|
+
end
|
18
|
+
|
19
|
+
# decorator:
|
20
|
+
def list(indexes)
|
21
|
+
indexes.collect { |i| self[i] }.join(" ")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
include PublicMethods
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
module IntegerIndexer
|
29
|
+
end
|
30
|
+
|
31
|
+
module CharIndexer
|
32
|
+
def [](char)
|
33
|
+
index = map.index(char)
|
34
|
+
super(index)
|
35
|
+
end
|
36
|
+
|
37
|
+
def evaluate(chars)
|
38
|
+
super(split(chars)) # "nit commit abc"
|
39
|
+
end
|
40
|
+
|
41
|
+
def index(file)
|
42
|
+
map[super]
|
43
|
+
end
|
44
|
+
|
45
|
+
def list(indexes)
|
46
|
+
super(split(indexes))
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def map
|
51
|
+
("a".."z").collect(&:to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def split(chars)
|
55
|
+
return chars unless chars.find { |c| c.length > 1 } # DISCUSS: what if "> aa bcd xx" where xx is actually an index?
|
56
|
+
chars.first.split("")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/nit/ignore.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Nit
|
2
|
+
class Ignore < Status
|
3
|
+
def initialize(*)
|
4
|
+
super
|
5
|
+
@ignores = Files.new(@config.ignored_files)
|
6
|
+
end
|
7
|
+
attr_reader :ignores
|
8
|
+
|
9
|
+
private
|
10
|
+
def process(state, indexes)
|
11
|
+
return show if indexes.size == 0
|
12
|
+
|
13
|
+
file_list = state.files.evaluate(indexes).compact
|
14
|
+
|
15
|
+
@config.ignored_files=(@config.ignored_files + file_list)
|
16
|
+
end
|
17
|
+
|
18
|
+
def show
|
19
|
+
return if ignores.size == 0
|
20
|
+
|
21
|
+
output = "Ignored files:\n"
|
22
|
+
ignores.each { |f| output << "[#{ignores.index(f)}] #{f}\n" }
|
23
|
+
|
24
|
+
output
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Unignore < Ignore
|
29
|
+
private
|
30
|
+
def process(state, indexes)
|
31
|
+
file_list = state.ignored.evaluate(indexes).compact
|
32
|
+
|
33
|
+
@config.ignored_files=(@config.ignored_files - file_list.map(&:to_s)) # FIXME: make this work with strings and File instances.
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/nit/lines.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module Nit
|
2
|
+
class Lines < Array
|
3
|
+
def initialize(text)
|
4
|
+
super(text.split("\n").collect { |ln| Line.new(ln, self) })
|
5
|
+
end
|
6
|
+
|
7
|
+
def find(pattern)
|
8
|
+
each do |ln|
|
9
|
+
next unless matches = ln.match(pattern)
|
10
|
+
|
11
|
+
yield ln, matches
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def files
|
16
|
+
files = []
|
17
|
+
|
18
|
+
for type, pattern in file_patterns
|
19
|
+
find(pattern) do |ln, matches|
|
20
|
+
files << file = File.new(matches[1].strip, ln)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
files
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
#private
|
32
|
+
def file_patterns
|
33
|
+
{
|
34
|
+
modified: /#\tmodified:(.+)/,
|
35
|
+
new: /#\t([^modified:].+)/
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Line < String
|
41
|
+
def initialize(string, screen)
|
42
|
+
super(string)
|
43
|
+
@screen = screen
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes the entire line from the screen.
|
47
|
+
def delete
|
48
|
+
@screen.delete(self)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class File
|
53
|
+
def initialize(path, line)
|
54
|
+
@path, @line = path, line
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_reader :path, :line
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
path.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|