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.
@@ -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
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ vendor/
16
+ working_set.log
@@ -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.
@@ -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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in working_set.gemspec
4
+ gemspec
@@ -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.
@@ -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
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
4
+ require "working_set_cli.rb"
@@ -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
@@ -0,0 +1,8 @@
1
+ module BasicActor
2
+
3
+ def self.included(includer)
4
+ includer.include Celluloid
5
+ includer.include Celluloid::Notifications
6
+ end
7
+
8
+ end
@@ -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