zeiger 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 +4 -4
- data/.zeiger.yml +2 -2
- data/README.md +20 -13
- data/bin/zeiger +4 -5
- data/lib/zeiger/file_info.rb +1 -1
- data/lib/zeiger/file_list_client.rb +5 -2
- data/lib/zeiger/index.rb +26 -8
- data/lib/zeiger/monitor.rb +14 -4
- data/lib/zeiger/query_client.rb +5 -2
- data/lib/zeiger/server.rb +23 -17
- data/lib/zeiger/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ca514e457ea27de32736575f07c6aabcd63e097
|
4
|
+
data.tar.gz: d01654cdb2af19a41953a1726ddf114fafc3db9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d61f59cd5a5b1d56dee4555bddc4c3b7573c37ebb6f52aa76a09ce6f80bc7f39b2a04db0d9ac463c6cbc439db8b312ac172ae09d4c5c696853fafeb72690c04
|
7
|
+
data.tar.gz: 5fa8f50cbefcff8298cc2896ff4053ab81d4bc360eb5f2c3dcd94196b8d97e844a6075630fa1b34d5b589ccd1290688ad25dc98c3417c61d73c21a9bc037904b
|
data/.zeiger.yml
CHANGED
data/README.md
CHANGED
@@ -1,30 +1,31 @@
|
|
1
1
|
# Zeiger
|
2
2
|
|
3
|
-
Zeiger is the German word for "pointer", "indicator", "index", "locator". This gem is built in the "index" sense
|
3
|
+
Zeiger is the German word for "pointer", "indicator", "index", "locator". This gem is built in the "index" sense. To install,
|
4
4
|
|
5
5
|
```
|
6
|
-
|
7
|
-
zeiger server
|
6
|
+
gem install zeiger
|
8
7
|
```
|
9
8
|
|
10
|
-
|
9
|
+
In a terminal, run
|
10
|
+
|
11
|
+
```
|
12
|
+
zeiger server
|
13
|
+
```
|
11
14
|
|
12
|
-
|
15
|
+
Zeiger will open a unix-socket under `/tmp` and listen for search and file-list requests. Run this in a terminal:
|
13
16
|
|
14
17
|
```
|
15
18
|
cd myproject
|
16
19
|
zeiger search "muppets"
|
17
20
|
```
|
18
21
|
|
19
|
-
|
22
|
+
(Replace "myproject" with something meaningful!)
|
20
23
|
|
21
|
-
|
24
|
+
Zeiger will index the current directory if it is not already indexed, then search for lines containing "muppets". Output is in the same format as `grep` (so you can hook it up with your emacs for quick project browsing).
|
25
|
+
|
26
|
+
Zeiger will rescan files in the current directory every ten seconds so the index is mostly up-to-date.
|
22
27
|
|
23
|
-
```
|
24
|
-
gem install 'zeiger'
|
25
|
-
```
|
26
28
|
|
27
|
-
This is built as a standalone commandline tool ; I don't have any use-cases for integrating it directly into a larger project. But if you do, I'm all ears.
|
28
29
|
|
29
30
|
## Usage
|
30
31
|
|
@@ -32,11 +33,11 @@ This is built as a standalone commandline tool ; I don't have any use-cases for
|
|
32
33
|
|
33
34
|
`zeiger search "foo"` writes the query to the socket and displays the result
|
34
35
|
|
35
|
-
`zeiger files "xed"` asks for the list of filenames corresponding to the argument ("xed"). With no argument, return all filenames.
|
36
|
+
`zeiger files "xed"` asks for the list of filenames corresponding to the argument ("xed"). With no argument, return all filenames. Files are sorted by length of filename. This sounds odd, but works nicely with 'completing-read in emacs: you will find the file you want in fewer keystrokes.
|
36
37
|
|
37
38
|
By default, Zeiger searches only in these subdirectories : %w{ app bin config lib spec test }, and excludes filenames matching these patterns: %w{ .gz$ .png$ .jpg$ .pdf$ }.
|
38
39
|
|
39
|
-
To override, create a file in your
|
40
|
+
To override, create a file called `.zeiger.yml` in your project root with the following format:
|
40
41
|
|
41
42
|
```yaml
|
42
43
|
search:
|
@@ -53,6 +54,12 @@ ignore:
|
|
53
54
|
- .mpg$
|
54
55
|
```
|
55
56
|
|
57
|
+
You should change the contents to suit your indexing needs. The `search` key is a list of regexps, zeiger will index only those files whose name matches at least one of these regexps. The `ignore` key is likewise a list of regexps, zeiger will not index any file whose name matches any of these regexps. The `ignore` rule supercedes the `search` rule.
|
58
|
+
|
59
|
+
When you invoke `zeiger search ...` or `zeiger files ...`, zeiger will consider whether an index already exists for the current directory. If not, and the current directory is a project root, it will create an index for the current directory. If there is no index, and the current directory is not a project root, it moves up one directory and tries again.
|
60
|
+
|
61
|
+
Zeiger considers a project root any directory containing any one of the following: `%w{ .zeiger.yml .git .hg Makefile Rakefile Gemfile build.xml }` (see `ROOT_FILES` constant in `index.rb`)
|
62
|
+
|
56
63
|
|
57
64
|
## Contributing
|
58
65
|
|
data/bin/zeiger
CHANGED
@@ -3,14 +3,13 @@
|
|
3
3
|
require 'socket'
|
4
4
|
require 'zeiger'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
pwd = `pwd`.strip
|
8
7
|
command = $*[0]
|
9
8
|
|
10
9
|
case command
|
11
|
-
when "server" ; Zeiger::Server.run *$*
|
12
|
-
when "search" ; Zeiger::QueryClient.run *$*
|
13
|
-
when "files" ; Zeiger::FileListClient.run *$*
|
10
|
+
when "server" ; Zeiger::Server.new.run *$*
|
11
|
+
when "search" ; Zeiger::QueryClient.run pwd, *$*
|
12
|
+
when "files" ; Zeiger::FileListClient.run pwd, *$*
|
14
13
|
end
|
15
14
|
|
16
15
|
# define file groups
|
data/lib/zeiger/file_info.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
module Zeiger
|
2
2
|
class FileListClient
|
3
|
-
def self.run command, q=nil, *args
|
3
|
+
def self.run pwd, command, q=nil, *args
|
4
4
|
Socket.unix(SOCKET_NAME) { |sock|
|
5
|
-
|
5
|
+
s = YAML.dump({ pwd: pwd, files: q })
|
6
|
+
sock.write([s.bytesize].pack("I"))
|
7
|
+
sock.write(s)
|
8
|
+
|
6
9
|
while !sock.eof?
|
7
10
|
puts sock.readline
|
8
11
|
end
|
data/lib/zeiger/index.rb
CHANGED
@@ -1,14 +1,27 @@
|
|
1
1
|
module Zeiger
|
2
|
+
INDICES = { }
|
3
|
+
|
2
4
|
class Index
|
5
|
+
ROOT_FILES = %w{ .zeiger.yml .git .hg Makefile Rakefile Gemfile build.xml }
|
3
6
|
NGRAM_SIZE = 3
|
4
7
|
|
5
|
-
attr_accessor :index, :dir, :includes, :ignore, :files
|
8
|
+
attr_accessor :index, :dir, :includes, :ignore, :files, :monitor
|
6
9
|
|
7
10
|
def initialize dir
|
8
11
|
attrs = File.exist?(".zeiger.yml") ? YAML.load(File.read ".zeiger.yml") : { }
|
9
12
|
self.dir = File.expand_path dir
|
10
13
|
self.index = Hash.new { |h, k| h[k] = [] }
|
11
14
|
self.files = Hash.new
|
15
|
+
self.monitor = Monitor.new dir, self
|
16
|
+
rescan
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_path path
|
20
|
+
raise "no path! #{path.inspect}" if path == nil || path.strip == ''
|
21
|
+
return INDICES[path] if INDICES[path]
|
22
|
+
return nil if path == '/'
|
23
|
+
return (INDICES[path] = new(path)) if ROOT_FILES.any? { |f| File.exist?(File.join path, f) }
|
24
|
+
return from_path(File.dirname path)
|
12
25
|
end
|
13
26
|
|
14
27
|
def remove_from_index file
|
@@ -32,19 +45,24 @@ module Zeiger
|
|
32
45
|
}
|
33
46
|
end
|
34
47
|
|
35
|
-
def
|
36
|
-
|
37
|
-
end
|
48
|
+
def rescan ; monitor.build_index ; end
|
49
|
+
def get_ngram_lines ngrams ; ngrams.map { |ngram| result = index[ngram] || [] }.reduce(&:&) ; end
|
50
|
+
def exec_query regex, ngrams ; get_ngram_lines(ngrams).select { |line| line.matches? regex } ; end
|
51
|
+
def sort_by_filename lines ; lines.sort_by { |line| line.file.local_filename } ; end
|
38
52
|
|
39
53
|
def query txt
|
40
54
|
puts "got query #{txt.inspect}"
|
41
|
-
exec_query Regexp.compile(txt), txt.ngrams(NGRAM_SIZE)
|
55
|
+
sort_by_filename exec_query Regexp.compile(Regexp.escape txt), txt.ngrams(NGRAM_SIZE)
|
42
56
|
end
|
43
57
|
|
44
58
|
def file_list name
|
45
|
-
|
46
|
-
|
47
|
-
|
59
|
+
if name
|
60
|
+
r = Regexp.compile name
|
61
|
+
puts "file names matching #{r.inspect}"
|
62
|
+
files.values.select { |f| f.match r }
|
63
|
+
else
|
64
|
+
files.values
|
65
|
+
end.sort_by { |f| f.local_filename.length }
|
48
66
|
end
|
49
67
|
end
|
50
68
|
end
|
data/lib/zeiger/monitor.rb
CHANGED
@@ -4,9 +4,19 @@ module Zeiger
|
|
4
4
|
|
5
5
|
def initialize dir, index
|
6
6
|
@dir, @index, @stat = dir, index, Hash.new
|
7
|
-
attrs =
|
8
|
-
@includes = attrs["
|
9
|
-
@ignore = attrs["ignore"]
|
7
|
+
attrs = load_config
|
8
|
+
@includes = attrs["search"] || %w{ app/**/* bin/**/* config/**/* lib/**/* spec/**/* test/**/* }
|
9
|
+
@ignore = attrs["ignore"] || %w{ .gz$ .png$ .jpg$ .pdf$ }
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_config
|
13
|
+
conf_file = File.join dir, ".zeiger.yml"
|
14
|
+
if File.exist?(conf_file)
|
15
|
+
puts "reading config from #{conf_file.inspect}"
|
16
|
+
YAML.load(File.read conf_file)
|
17
|
+
else
|
18
|
+
{ }
|
19
|
+
end
|
10
20
|
end
|
11
21
|
|
12
22
|
def ignore? filename
|
@@ -21,7 +31,7 @@ module Zeiger
|
|
21
31
|
started = Time.now
|
22
32
|
files = Set.new
|
23
33
|
includes.each do |inc|
|
24
|
-
Dir.glob(File.join(dir, inc
|
34
|
+
Dir.glob(File.join(dir, inc)).sort.each do |file|
|
25
35
|
if File.file?(file) && !ignore?(file)
|
26
36
|
files << file
|
27
37
|
mtime = File.stat(file).mtime
|
data/lib/zeiger/query_client.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
module Zeiger
|
2
2
|
class QueryClient
|
3
|
-
def self.run command, q, *args
|
3
|
+
def self.run pwd, command, q, *args
|
4
4
|
Socket.unix(SOCKET_NAME) { |sock|
|
5
|
-
|
5
|
+
s = YAML.dump({ pwd: pwd, search: q })
|
6
|
+
sock.write([s.bytesize].pack("I"))
|
7
|
+
sock.write(s)
|
8
|
+
|
6
9
|
while !sock.eof?
|
7
10
|
puts sock.readline
|
8
11
|
end
|
data/lib/zeiger/server.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
module Zeiger
|
2
|
-
|
3
|
-
def self.run command, *args
|
4
|
-
dir = File.expand_path(".")
|
5
|
-
z = Zeiger::Index.new dir
|
4
|
+
SOCKET_NAME = "/tmp/zeiger-index"
|
6
5
|
|
6
|
+
class Server
|
7
|
+
def run command, *args
|
7
8
|
Thread.new do
|
8
9
|
begin
|
9
|
-
puts "monitor thread"
|
10
|
-
monitor = Zeiger::Monitor.new dir, z
|
11
|
-
puts "created monitor"
|
12
10
|
while true do
|
13
|
-
|
14
|
-
|
11
|
+
indices = Zeiger::INDICES.values
|
12
|
+
indices.each do |index|
|
13
|
+
puts "scanning #{index.dir}"
|
14
|
+
index.rescan
|
15
|
+
end
|
15
16
|
sleep 10
|
16
17
|
end
|
17
18
|
rescue Exception => e
|
@@ -20,18 +21,23 @@ module Zeiger
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
puts "query thread..."
|
24
|
-
|
25
24
|
Socket.unix_server_loop(SOCKET_NAME) { |sock, client|
|
26
25
|
puts "query thread: server loop"
|
27
26
|
begin
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
length = sock.read(4).unpack("I")[0]
|
28
|
+
query = sock.read(length)
|
29
|
+
incoming = YAML.load(query)
|
30
|
+
puts incoming.to_yaml
|
31
|
+
|
32
|
+
index = Index.from_path incoming[:pwd]
|
33
|
+
puts "querying index at #{index.dir}"
|
34
|
+
|
35
|
+
if incoming[:search]
|
36
|
+
index.query(incoming[:search]).each { |res| sock.puts res.to_s }
|
37
|
+
elsif incoming.key? :files
|
38
|
+
index.file_list(incoming[:files]).each { |f| sock.puts f.local_filename }
|
34
39
|
end
|
40
|
+
|
35
41
|
ensure
|
36
42
|
sock.close
|
37
43
|
end
|
data/lib/zeiger/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zeiger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- conanite
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|