working_set 1.0.1
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 +7 -0
- data/.gitignore +16 -0
- data/.ruby-version +1 -0
- data/API_FOR_EDITOR_INTEGRATION.md +97 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +2 -0
- data/bin/working_set +4 -0
- data/lib/api_input_actor.rb +75 -0
- data/lib/basic_actor.rb +8 -0
- data/lib/colors.rb +16 -0
- data/lib/live_updater_actor.rb +29 -0
- data/lib/set_builder_actor.rb +23 -0
- data/lib/set_builder_adapter.rb +2 -0
- data/lib/set_builder_adapter/ag.rb +132 -0
- data/lib/set_viewer_actor.rb +146 -0
- data/lib/user_input_actor.rb +177 -0
- data/lib/view/base.rb +13 -0
- data/lib/view/help.rb +28 -0
- data/lib/view/welcome_user.rb +40 -0
- data/lib/view/working_set.rb +313 -0
- data/lib/working_set.rb +34 -0
- data/lib/working_set_cli.rb +205 -0
- data/lib/working_set_item.rb +40 -0
- data/working_set.gemspec +35 -0
- metadata +226 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8d080e5e195b802c64757728b39a21a747e029c9a067bd523a115208aed4038
|
4
|
+
data.tar.gz: b02705986887a8ff43aeb8945e3356032f97b2ed6e05458f4438e2b55e1f5ded
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b5699a5b2f85909e67ec262ed787ba94e47015874fb4e931b0bd646229bb09ae8b1737705273d3152bcbc54dabda3a50adc3033c49332c4d2133cd03c1e5963a
|
7
|
+
data.tar.gz: 119b23428f7bbbae2025c186371c0a857927cd58230b153c6b327c77d0234b17054a50ae81760d8e9f8b27554dcea8f7cef73be61db0f99838cacecbfa354c1a
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.1
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# API for Editor Integration
|
2
|
+
|
3
|
+
Most advanced text editors can be extended with plugins and other
|
4
|
+
customizations. Working Set was built to be a companion to your text editor.
|
5
|
+
Since the original author of Working Set uses Vim, that's the first editor
|
6
|
+
integration that was created.
|
7
|
+
|
8
|
+
At time of writing, it's also the only one that exists.
|
9
|
+
|
10
|
+
Should someone wish to integrate another editor, e.g. Emacs, this is the
|
11
|
+
information they'd need to know.
|
12
|
+
|
13
|
+
## Overview
|
14
|
+
|
15
|
+
When `working_set` (WS) starts, it creates a socket file in the current
|
16
|
+
directory (named `.working_set_socket` by default). WS listens to the socket for
|
17
|
+
`message`s. When it receives a `message`, it will asyncronously perform whatever
|
18
|
+
task is required, and then (possibly) send a `message` as a response to the
|
19
|
+
client via the socket file.
|
20
|
+
|
21
|
+
You can see a working client implementation in the [Vim
|
22
|
+
plugin](https://github.com/coderifous/working-set.vim).
|
23
|
+
|
24
|
+
## Message Format
|
25
|
+
|
26
|
+
Messages to Working Set are serialized JSON and have these keys:
|
27
|
+
|
28
|
+
message: a single word, often a command
|
29
|
+
|
30
|
+
args: optional object, specific to a command.
|
31
|
+
|
32
|
+
options: optional object, specific to a command.
|
33
|
+
|
34
|
+
Replies from Working Set will be similiar, always having a `message` key, but
|
35
|
+
additional keys may vary.
|
36
|
+
|
37
|
+
## Messages from Client to Server (Working Set)
|
38
|
+
|
39
|
+
#### search_changed
|
40
|
+
|
41
|
+
This message tells Working Set to update the search results.
|
42
|
+
|
43
|
+
Examples:
|
44
|
+
|
45
|
+
{ "message": "search_changed", "args": "foo" }
|
46
|
+
|
47
|
+
{ "message": "search_changed", "args": "foo", "options": { "whole_word": true } }
|
48
|
+
|
49
|
+
#### select_next_item, et al
|
50
|
+
|
51
|
+
This message tells Working Set to select the next item in the list. There are a
|
52
|
+
few similar messages.
|
53
|
+
|
54
|
+
Example:
|
55
|
+
|
56
|
+
{ "message": "select_next_item" }
|
57
|
+
|
58
|
+
Similar messages:
|
59
|
+
* select_prev_item
|
60
|
+
* select_next_file
|
61
|
+
* select_prev_file
|
62
|
+
|
63
|
+
### tell_selected_item
|
64
|
+
|
65
|
+
Working Set will respond to this message with a "selected_item" message.
|
66
|
+
|
67
|
+
### tell_selected_item_content
|
68
|
+
|
69
|
+
Working Set will respond to this message with a "selected_item_content" message.
|
70
|
+
|
71
|
+
### show_match_lines_toggled
|
72
|
+
|
73
|
+
Working Set will toggle whether match lines are showed.
|
74
|
+
|
75
|
+
### refresh
|
76
|
+
|
77
|
+
Working Set will re-run the current search and update results.
|
78
|
+
|
79
|
+
## Messages from Server to Client (editor)
|
80
|
+
|
81
|
+
### selected_item
|
82
|
+
|
83
|
+
Example:
|
84
|
+
|
85
|
+
{ "message": "selected_item", "file_path": "app/foo.rb", "row": 1, "column": 10 }
|
86
|
+
|
87
|
+
Clients can do whatever they want when they recieve this message, one useful
|
88
|
+
response might be to jump to the specified file and location.
|
89
|
+
|
90
|
+
### selected_item_content
|
91
|
+
|
92
|
+
Example:
|
93
|
+
|
94
|
+
{ "message": "selected_item_content", data: "foo bar baz" }
|
95
|
+
|
96
|
+
Clients can do whatever they want when they recieve this message, one useful
|
97
|
+
response might be to insert the requested content where the user is typing.
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## [v1.0.1] - 2020-09-07
|
4
|
+
|
5
|
+
### Fixed
|
6
|
+
* Fix issue with scrolling via up/down arrows
|
7
|
+
* Fix issue with preserving whole_word option on refresh
|
8
|
+
|
9
|
+
## [v1.0.0] - 2020-09-05
|
10
|
+
|
11
|
+
### Initial Release
|
12
|
+
* Refactoring and prep for release.
|
13
|
+
* Features search and navigation features.
|
14
|
+
|
15
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Jim Garvin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# working_set
|
2
|
+
|
3
|
+
Companion to your editor that makes searching, and using search results for
|
4
|
+
jumping around, super nice.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Installing the gem adds the working_set command to your path.
|
9
|
+
|
10
|
+
$ gem install working_set
|
11
|
+
|
12
|
+
Install the plugin for your editor.
|
13
|
+
|
14
|
+
* [Vim Plugin](https://github.com/coderifous/working-set.vim)
|
15
|
+
|
16
|
+
Note: Currently there's only a plugin for Vim, however Working Set will be
|
17
|
+
compatible with any editor that can be extended and communicate via socket.
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Run the working_set command in your project's directory.
|
22
|
+
|
23
|
+
$ cd my-project
|
24
|
+
$ working_set
|
25
|
+
|
26
|
+
working_set is now running, listening on a file socket, ready to receive
|
27
|
+
commands from your text editor which you should run in a separate terminal but
|
28
|
+
in the same directory.
|
29
|
+
|
30
|
+
$ cd my-project
|
31
|
+
$ vim
|
32
|
+
|
33
|
+
## Options
|
34
|
+
|
35
|
+
Run `working_set -h` to see a list of command line options:
|
36
|
+
|
37
|
+
--watch | -w
|
38
|
+
|
39
|
+
Tells working_set to monitor the filesystem for changes and refresh the
|
40
|
+
search results automatically when changes are detected. The value should be
|
41
|
+
point at the directory you want to monitor.
|
42
|
+
|
43
|
+
Example: --watch=app
|
44
|
+
|
45
|
+
Default: none, search results will not automatically refresh.
|
46
|
+
|
47
|
+
--context | -c
|
48
|
+
|
49
|
+
Sets number of contextual lines to show around matches.
|
50
|
+
|
51
|
+
Example: --count=3
|
52
|
+
|
53
|
+
Default: 1
|
54
|
+
|
55
|
+
--socket | -s
|
56
|
+
|
57
|
+
Sets the path for the socket file to create.
|
58
|
+
|
59
|
+
Example: --socket=/tmp/my-special-project
|
60
|
+
|
61
|
+
Default: .working_set_socket
|
62
|
+
|
63
|
+
--help | -h
|
64
|
+
|
65
|
+
Show help.
|
66
|
+
|
67
|
+
## Commands in working_set
|
68
|
+
|
69
|
+
You can press '?' in working_set to see key bindings:
|
70
|
+
|
71
|
+
? - display help
|
72
|
+
q - quit
|
73
|
+
j - select next match
|
74
|
+
k - select previous match
|
75
|
+
ctrl-n - select first match in next file
|
76
|
+
ctrl-p - select first match in previous file
|
77
|
+
enter - Tell editor to jump to match
|
78
|
+
down arrow - scroll down without changing selection
|
79
|
+
up arrow - scroll up without changing selection
|
80
|
+
r - refresh search results
|
81
|
+
[ - decrease context lines
|
82
|
+
] - increase context lines
|
83
|
+
z - toggle showing match lines vs just matched files
|
84
|
+
y - copy selected match to system clipboard
|
85
|
+
Y - copy selected match + context to system clipboard
|
86
|
+
|
87
|
+
## Todo
|
88
|
+
* Add support for searching straight from working_set using "/" key.
|
89
|
+
* Add support for setting search argument prefix as working_set command argument.
|
90
|
+
e.g. --prefix="--ignore=tmp,vendor"
|
91
|
+
* Add support for bookmarks.
|
92
|
+
* Add support for search history.
|
93
|
+
* Add support for customizing key bindings.
|
94
|
+
* Document protocol so other plugin editors can exist.
|
95
|
+
* Document adapter so other search tools can be used.
|
96
|
+
|
97
|
+
## Development
|
98
|
+
|
99
|
+
1) Fork the repo, clone the source code.
|
100
|
+
2) run `bundle install` to install dependencies.
|
101
|
+
3) run `bin/working_set -d` to execute the program with debug logging enabled
|
102
|
+
4) watch the debug messages: `tail -f working_set.log`
|
103
|
+
5) make code changes, restart `working_set` to see their effect.
|
104
|
+
|
105
|
+
Please do submit pull requests to add features, fix bugs, etc. Please discuss
|
106
|
+
before spending lots of time on large changes.
|
107
|
+
|
data/Rakefile
ADDED
data/bin/working_set
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class ApiInputActor
|
5
|
+
include BasicActor
|
6
|
+
include Celluloid::IO
|
7
|
+
|
8
|
+
finalizer :close_server
|
9
|
+
|
10
|
+
# Since the inputs are translated into internal actor messages, we can have a
|
11
|
+
# little extra security by only permitting certain messages, because some
|
12
|
+
# messages are really for internal use only.
|
13
|
+
PERMITTED_MESSAGES_LIST = %w(
|
14
|
+
search_changed
|
15
|
+
select_next_item
|
16
|
+
select_prev_item
|
17
|
+
select_next_file
|
18
|
+
select_prev_file
|
19
|
+
tell_selected_item
|
20
|
+
tell_selected_item_content
|
21
|
+
show_match_lines_toggled
|
22
|
+
refresh
|
23
|
+
)
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
subscribe "respond_client", :respond_client
|
27
|
+
@server = UNIXServer.new $SOCKET_PATH
|
28
|
+
async.watch_input
|
29
|
+
end
|
30
|
+
|
31
|
+
def watch_input
|
32
|
+
loop do
|
33
|
+
@client = @server.accept
|
34
|
+
while input = @client.gets
|
35
|
+
process_input(input.chomp)
|
36
|
+
end
|
37
|
+
@client.close
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process_input(input)
|
42
|
+
debug_message "input: #{input.inspect}"
|
43
|
+
|
44
|
+
parsed = JSON.parse(input)
|
45
|
+
message = parsed["message"]
|
46
|
+
args = parsed["args"]
|
47
|
+
options = parsed["options"]
|
48
|
+
|
49
|
+
debug_message "message: #{message.inspect}\nargs: #{args.inspect}\noptions: #{options.inspect}"
|
50
|
+
|
51
|
+
unless PERMITTED_MESSAGES_LIST.include?(message)
|
52
|
+
debug_message "Message not permitted, ignoring."
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
publish *[message, args, options].compact
|
57
|
+
end
|
58
|
+
|
59
|
+
def close_server
|
60
|
+
debug_message "closing server" if @server
|
61
|
+
@server.close if @server
|
62
|
+
File.delete($SOCKET_PATH)
|
63
|
+
end
|
64
|
+
|
65
|
+
def respond_client(_, message, extras={})
|
66
|
+
payload = { message: message }.merge(extras)
|
67
|
+
debug_message "Responding #{payload.inspect}"
|
68
|
+
@client.puts payload.to_json if @client
|
69
|
+
end
|
70
|
+
|
71
|
+
def send_message(msg, arg)
|
72
|
+
debug_message "Sending #{msg}, #{arg}"
|
73
|
+
@client.puts [msg, arg].join("|") if @client
|
74
|
+
end
|
75
|
+
end
|
data/lib/basic_actor.rb
ADDED
data/lib/colors.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
if defined?(Ncurses)
|
2
|
+
Colors = {
|
3
|
+
blue: { pair: [Ncurses::COLOR_BLUE, -1] },
|
4
|
+
cyan: { pair: [Ncurses::COLOR_CYAN, -1] },
|
5
|
+
red: { pair: [Ncurses::COLOR_RED, -1] },
|
6
|
+
white: { pair: [Ncurses::COLOR_WHITE, -1] },
|
7
|
+
green: { pair: [Ncurses::COLOR_GREEN, -1] },
|
8
|
+
yellow: { pair: [Ncurses::COLOR_YELLOW, -1] }
|
9
|
+
}
|
10
|
+
|
11
|
+
Colors.each_with_index do |(k,v),i|
|
12
|
+
v[:number] = i + 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
API_PORT_NUMBER = 3930
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'listen'
|
2
|
+
|
3
|
+
class LiveUpdaterActor
|
4
|
+
include BasicActor
|
5
|
+
|
6
|
+
finalizer :stop
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@listener = build
|
10
|
+
start
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
Listen.to($LIVE_UPDATE_WATCH_PATH) do |modified, added, removed|
|
15
|
+
debug_message "modified absolute path: #{modified}"
|
16
|
+
debug_message "added absolute path: #{added}"
|
17
|
+
debug_message "removed absolute path: #{removed}"
|
18
|
+
publish "refresh"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
@listener.start
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop
|
27
|
+
@listener.stop
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class SetBuilderActor
|
2
|
+
include BasicActor
|
3
|
+
|
4
|
+
attr_accessor :adapter
|
5
|
+
|
6
|
+
DEFAULT_ADAPTER_CLASS = SetBuilderAdapter::Ag
|
7
|
+
|
8
|
+
def initialize(initial_adapter = DEFAULT_ADAPTER_CLASS.new)
|
9
|
+
subscribe "search_changed", :build_working_set
|
10
|
+
self.adapter = initial_adapter
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_working_set(_, search, options={})
|
14
|
+
debug_message "search: #{search.inspect} options: #{options.inspect}"
|
15
|
+
begin
|
16
|
+
working_set = adapter.build_working_set(search, options)
|
17
|
+
publish "set_build_finished", working_set
|
18
|
+
rescue StandardError => e
|
19
|
+
publish "set_build_failed", e
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|