qtool 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README.mdown +29 -0
- data/Rakefile +7 -0
- data/bin/q +10 -0
- data/lib/q.rb +40 -0
- data/lib/q/command.rb +23 -0
- data/lib/q/commands/glob.rb +71 -0
- data/lib/q/commands/help.rb +25 -0
- data/lib/q/commands/search.rb +19 -0
- metadata +70 -0
data/.gitignore
ADDED
data/README.mdown
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#q is for query
|
2
|
+
|
3
|
+
q is a small tool for performing repetitive tasks from the console. Where you use rake to automate a project’s tasks, you’d use q to automate your own workflow a little. q commands are relatively free-form, with a few built-in ones that I use frequently enough:
|
4
|
+
|
5
|
+
1. Searching via Google:
|
6
|
+
|
7
|
+
q search search terms
|
8
|
+
|
9
|
+
Searches for the passed-in terms on Google. Synonyms are `google`, `g`.
|
10
|
+
|
11
|
+
|
12
|
+
2. Looking up Wikipedia articles:
|
13
|
+
|
14
|
+
q wikipedia toast
|
15
|
+
|
16
|
+
Looks up the named article on Wikipedia. A synonym is `wp`.
|
17
|
+
|
18
|
+
|
19
|
+
3. Looking up Ruby core class docs:
|
20
|
+
|
21
|
+
q ruby Hash
|
22
|
+
|
23
|
+
Looks up the docs for Hash on ruby-doc.org. A synonym is `rb`.
|
24
|
+
|
25
|
+
4. Looking up Cocoa/related documentation:
|
26
|
+
|
27
|
+
q ns Array
|
28
|
+
|
29
|
+
Looks up the docs for NSArray in the on-disk filesystem (uses globbing to find them); therefore it doesn’t require an internet connection and finishes very quickly. Synonyms are: ca, cf, cg, dom, eagl, gl, glu, ib, qt, ui, web.
|
data/Rakefile
ADDED
data/bin/q
ADDED
data/lib/q.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Q
|
2
|
+
@@registered_commands = {}
|
3
|
+
@@unique_commands = []
|
4
|
+
|
5
|
+
def self.register_command(shortcut, command)
|
6
|
+
if shortcut.is_a? Array
|
7
|
+
shortcut.each do |s|
|
8
|
+
register_command(s, command)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
@@registered_commands[shortcut.to_sym] = command
|
12
|
+
@@unique_commands << command unless @@unique_commands.include? command
|
13
|
+
command.registered_shortcuts << shortcut.to_sym
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.commands
|
18
|
+
@@registered_commands
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.unique_commands
|
22
|
+
@@unique_commands
|
23
|
+
end
|
24
|
+
|
25
|
+
require "q/command"
|
26
|
+
require "q/commands/glob"
|
27
|
+
require "q/commands/help"
|
28
|
+
require "q/commands/search"
|
29
|
+
|
30
|
+
DEFAULT_SHORTCUT = :search
|
31
|
+
SHORTCUT = if ARGV.empty?
|
32
|
+
:help
|
33
|
+
elsif @@registered_commands.has_key? ARGV.first.to_sym
|
34
|
+
ARGV.shift.to_sym
|
35
|
+
else
|
36
|
+
DEFAULT_SHORTCUT
|
37
|
+
end
|
38
|
+
|
39
|
+
puts @@registered_commands[SHORTCUT].execute(SHORTCUT, ARGV)
|
40
|
+
end
|
data/lib/q/command.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Q
|
2
|
+
class Command
|
3
|
+
def initialize(usage)
|
4
|
+
@usage = usage
|
5
|
+
@registered_shortcuts = []
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
def execute(shortcut, terms)
|
10
|
+
"#{shortcut} is unimplemented"
|
11
|
+
end
|
12
|
+
|
13
|
+
def help(shortcut, terms)
|
14
|
+
usage || "#{shortcut} is undocumented"
|
15
|
+
end
|
16
|
+
|
17
|
+
def usage
|
18
|
+
registered_shortcuts.map{ |shortcut| shortcut.to_s }.join("|") + " " + @usage
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :registered_shortcuts
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Q
|
2
|
+
class Glob < Command
|
3
|
+
def initialize(patterns, usage)
|
4
|
+
@patterns = patterns
|
5
|
+
super(usage)
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute(shortcut, terms)
|
9
|
+
matches = []
|
10
|
+
@patterns.each do |pattern|
|
11
|
+
matches = Dir.glob(interpolate_pattern(pattern, [shortcut.to_s] + terms))
|
12
|
+
unless matches.empty?
|
13
|
+
%x{open -a Safari "#{matches.first}"}
|
14
|
+
break
|
15
|
+
end
|
16
|
+
end
|
17
|
+
matches.first
|
18
|
+
end
|
19
|
+
|
20
|
+
def help(shortcut, terms)
|
21
|
+
short = usage
|
22
|
+
if terms.include?("-v") or terms.include?("--verbose")
|
23
|
+
long = $/ + @patterns.join($/) + $/ + $/ + "(%{0}, %{1}, ... are replaced with the shortcut and terms)"
|
24
|
+
short + $/ + long
|
25
|
+
else
|
26
|
+
short + $/ + "(use `q help #{shortcut} --verbose` or `q help #{shortcut} -v` for the relevant patterns)"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def interpolate_pattern(pattern, terms)
|
33
|
+
pattern.gsub(/%\{(\d+?)\}/) do |match|
|
34
|
+
terms[$1.to_i]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
DOCSET_PATHS = [ # docsets to search within
|
40
|
+
"/Library/Developer/Shared/Documentation/DocSets/*.docset",
|
41
|
+
"/Developer/Documentation/DocSets/*.docset",
|
42
|
+
"/Developer/Platforms/*.platform/Developer/Documentation/DocSets/*.docset"
|
43
|
+
]
|
44
|
+
DOCSET_CONTENTS_PATH = "/Contents/Resources/Documents/documentation/*/Reference/"
|
45
|
+
PATTERNS = [ # these patterns are matched within <docset>/Contents/Resources/Documents/documentation/*/Reference/
|
46
|
+
"%{0}%{1}/Reference/reference.html", # iPhone/CoreGraphics
|
47
|
+
"%{0}%{1}Ref/index.html", # iPhone CoreFoundation
|
48
|
+
"%{0}%{1}Ref/Reference/reference.html", # CoreFoundation
|
49
|
+
"%{0}%{1}_Class/%{0}%{1}/%{0}%{1}.html", # iPhone/UIKit
|
50
|
+
"%{0}%{1}_Class/%{0}%{1}ClassReference/%{0}%{1}ClassReference.html",
|
51
|
+
"%{0}%{1}_Class/Introduction/Introduction.html",
|
52
|
+
"%{0}%{1}_class/Reference/%{0}%{1}.html",
|
53
|
+
"%{0}%{1}_class/Reference/Reference.html",
|
54
|
+
"%{0}%{1}_ClassRef/Reference/%{0}%{1}.html", # iPhone/OpenGL ES
|
55
|
+
"%{0}%{1}_protocol/Reference/%{0}%{1}.html",
|
56
|
+
"%{0}%{1}_protocol/Reference/Reference.html",
|
57
|
+
"*/Protocols/%{0}%{1}_protocol/Reference/Reference.html",
|
58
|
+
"*/Classes/%{0}%{1}_Class/Introduction/Introduction.html",
|
59
|
+
"*/Classes/%{0}%{1}_Class/Reference/%{0}%{1}.html",
|
60
|
+
"*/Classes/%{0}%{1}_Class/Reference/Reference.html",
|
61
|
+
"Foundation/Classes/%{0}%{1}_Class/Reference/Reference.html",
|
62
|
+
"ManPages/man3/%{0}%{1}.3.html", # man pages, e.g. OpenGL man pages
|
63
|
+
"*/Classes/%{0}%{1}_Class/%{0}%{1}.html",
|
64
|
+
"*/Classes/%{0}%{1}_WebKitAdditions/Reference/Reference.html",
|
65
|
+
]
|
66
|
+
PATTERN_PATHS = (DOCSET_PATHS.reduce([]){ |memo, docset_path| memo + PATTERNS.collect{ |pattern| docset_path + DOCSET_CONTENTS_PATH + pattern } }).flatten
|
67
|
+
|
68
|
+
PREFIXES = %w(ca cf cg dom eagl gl glu ib ns qt ui web)
|
69
|
+
|
70
|
+
register_command(PREFIXES.collect{ |prefix| prefix.to_sym }, Glob.new(PATTERN_PATHS, "CLASS -- glob through Cocoa documentation for CLASS"))
|
71
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Q
|
2
|
+
class Help < Command
|
3
|
+
def initialize
|
4
|
+
super("COMMAND -- print help for COMMAND")
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(shortcut, terms)
|
8
|
+
shortcut = terms.shift.to_sym unless terms.empty?
|
9
|
+
if command = Q.commands[shortcut]
|
10
|
+
command.help(shortcut, terms)
|
11
|
+
else
|
12
|
+
shortcut.to_s + ": unknown command"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def help(shortcut, terms)
|
17
|
+
([ %q{Usage: q [SHORTCUT] [TERM] ...},
|
18
|
+
%q{Perform the command specified by SHORTCUT for the specified TERMs.},
|
19
|
+
""
|
20
|
+
] + Q.unique_commands.map{ |command| " " + command.usage }.sort).join($/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
register_command(:help, Help.new)
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Q
|
2
|
+
class Search < Command
|
3
|
+
def initialize(url_pattern, usage)
|
4
|
+
@url_pattern = url_pattern
|
5
|
+
super(usage)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
def execute(shortcut, terms)
|
10
|
+
url = @url_pattern % terms.join("+")
|
11
|
+
%x{osascript -e 'open location "#{url}"'}
|
12
|
+
url
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
register_command([:search, :google, :g], Search.new("http://www.google.com/search?q=%s", "TERM ... -- search for TERMs on google"))
|
17
|
+
register_command([:ruby, :rb], Search.new("http://ruby-doc.org/core/classes/%s.html", "CLASS -- look up CLASS on ruby-doc.org"))
|
18
|
+
register_command([:wikipedia, :wp], Search.new("http://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go", "ARTICLE -- look up [article] on wikipedia"))
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qtool
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Rob Rix
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-07-08 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Automate bits of your everyday workflow with q commands.
|
22
|
+
email: rob@monochromeindustries.com
|
23
|
+
executables:
|
24
|
+
- q
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- .gitignore
|
31
|
+
- README.mdown
|
32
|
+
- Rakefile
|
33
|
+
- bin/q
|
34
|
+
- lib/q.rb
|
35
|
+
- lib/q/command.rb
|
36
|
+
- lib/q/commands/glob.rb
|
37
|
+
- lib/q/commands/help.rb
|
38
|
+
- lib/q/commands/search.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: https://github.com/robrix/q/
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.6
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: q is for query.
|
69
|
+
test_files: []
|
70
|
+
|