text_editor 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +33 -0
- data/.ruby-version +1 -0
- data/.text_editor.rb +9 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +20 -0
- data/README.org +29 -0
- data/bin/console +9 -0
- data/bin/te +3 -0
- data/lib/core_ext/hash.rb +12 -0
- data/lib/core_ext/pathname.rb +9 -0
- data/lib/text_editor/buffer.rb +85 -0
- data/lib/text_editor/clipboard/cygwin.rb +20 -0
- data/lib/text_editor/clipboard/linux.rb +17 -0
- data/lib/text_editor/clipboard/mac.rb +18 -0
- data/lib/text_editor/clipboard/unknown.rb +17 -0
- data/lib/text_editor/clipboard/windows.rb +17 -0
- data/lib/text_editor/clipboard.rb +18 -0
- data/lib/text_editor/command/backspace.rb +26 -0
- data/lib/text_editor/command/cursor_down.rb +14 -0
- data/lib/text_editor/command/cursor_end.rb +10 -0
- data/lib/text_editor/command/cursor_left.rb +16 -0
- data/lib/text_editor/command/cursor_right.rb +19 -0
- data/lib/text_editor/command/cursor_start.rb +10 -0
- data/lib/text_editor/command/cursor_up.rb +13 -0
- data/lib/text_editor/command/insert_char.rb +11 -0
- data/lib/text_editor/command/insert_line.rb +16 -0
- data/lib/text_editor/command/insert_tab.rb +9 -0
- data/lib/text_editor/command/quit.rb +9 -0
- data/lib/text_editor/command/resolver.rb +36 -0
- data/lib/text_editor/command/write_file.rb +13 -0
- data/lib/text_editor/command.rb +26 -0
- data/lib/text_editor/component.rb +13 -0
- data/lib/text_editor/configuration/bootstrap.rb +43 -0
- data/lib/text_editor/configuration/dsl.rb +11 -0
- data/lib/text_editor/configuration/resolver.rb +45 -0
- data/lib/text_editor/configuration.rb +15 -0
- data/lib/text_editor/cursor.rb +42 -0
- data/lib/text_editor/keyboard.rb +54 -0
- data/lib/text_editor/mode/nano.rb +30 -0
- data/lib/text_editor/mode.rb +23 -0
- data/lib/text_editor/operating_system.rb +19 -0
- data/lib/text_editor/reactor.rb +38 -0
- data/lib/text_editor/state.rb +10 -0
- data/lib/text_editor/terminal.rb +57 -0
- data/lib/text_editor/window.rb +44 -0
- data/lib/text_editor.rb +121 -0
- data/log/.keep +0 -0
- data/spec/core_ext/hash_spec.rb +15 -0
- data/spec/core_ext/pathname_spec.rb +26 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/text_editor/buffer_spec.rb +181 -0
- data/spec/text_editor/clipboard_spec.rb +28 -0
- data/spec/text_editor/command/quit_spec.rb +14 -0
- data/spec/text_editor/command/resolver_spec.rb +56 -0
- data/spec/text_editor/command_spec.rb +85 -0
- data/spec/text_editor/component_spec.rb +40 -0
- data/spec/text_editor/configuration_spec.rb +25 -0
- data/spec/text_editor/cursor_spec.rb +93 -0
- data/spec/text_editor/operating_system_spec.rb +55 -0
- data/spec/text_editor/reactor_spec.rb +34 -0
- data/spec/text_editor/state_spec.rb +20 -0
- data/text_editor.gemspec +18 -0
- metadata +143 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Configuration
|
3
|
+
class Bootstrap
|
4
|
+
include Component
|
5
|
+
|
6
|
+
def configure(args)
|
7
|
+
namespace.instance = editor
|
8
|
+
|
9
|
+
options.order!(args)
|
10
|
+
options.parse!(args)
|
11
|
+
|
12
|
+
config.files = args.map do |file|
|
13
|
+
Pathname.new(file)
|
14
|
+
end
|
15
|
+
|
16
|
+
resolver.files.each do |file|
|
17
|
+
require file
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def options
|
22
|
+
@options ||= OptionParser.new do |opts|
|
23
|
+
opts.on("--log [FILE]") { |log| config.log = log }
|
24
|
+
|
25
|
+
opts.on("--version") do
|
26
|
+
puts editor.version
|
27
|
+
raise SystemExit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def resolver
|
35
|
+
@resolver ||= Resolver.new(editor)
|
36
|
+
end
|
37
|
+
|
38
|
+
def namespace
|
39
|
+
Module.nesting.last
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Configuration
|
3
|
+
class Resolver
|
4
|
+
include Component
|
5
|
+
|
6
|
+
FILE = ".text_editor.rb"
|
7
|
+
|
8
|
+
def files
|
9
|
+
@files ||= configs.select(&:exist?)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def configs
|
15
|
+
directories.map do |directory|
|
16
|
+
directory.join(FILE)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def directories
|
21
|
+
[editor.root, etc, home, *tree].uniq
|
22
|
+
end
|
23
|
+
|
24
|
+
def etc
|
25
|
+
Pathname.new("/etc")
|
26
|
+
end
|
27
|
+
|
28
|
+
def home
|
29
|
+
Pathname.new(ENV["HOME"])
|
30
|
+
end
|
31
|
+
|
32
|
+
def pwd
|
33
|
+
Pathname.new(Dir.pwd)
|
34
|
+
end
|
35
|
+
|
36
|
+
def tree
|
37
|
+
[pwd].tap do |tree|
|
38
|
+
until [home, tree.first].include?(tree.first.dirname)
|
39
|
+
tree.unshift(tree.first.dirname)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Cursor
|
3
|
+
attr_reader :line, :column
|
4
|
+
|
5
|
+
def initialize(line = 0, column = 0)
|
6
|
+
@line = line
|
7
|
+
@column = column
|
8
|
+
end
|
9
|
+
|
10
|
+
def clamp(line, column)
|
11
|
+
line = [@line, line].min
|
12
|
+
column = [@column, column].min
|
13
|
+
move(line, column)
|
14
|
+
end
|
15
|
+
|
16
|
+
def down(count = 1)
|
17
|
+
move(line + count, column)
|
18
|
+
end
|
19
|
+
|
20
|
+
def left(count = 1)
|
21
|
+
move(line, column - count)
|
22
|
+
end
|
23
|
+
|
24
|
+
def move(line, column)
|
25
|
+
line = [line, 0].max
|
26
|
+
column = [column, 0].max
|
27
|
+
self.class.new(line, column)
|
28
|
+
end
|
29
|
+
|
30
|
+
def position
|
31
|
+
[line, column]
|
32
|
+
end
|
33
|
+
|
34
|
+
def right(count = 1)
|
35
|
+
move(line, column + count)
|
36
|
+
end
|
37
|
+
|
38
|
+
def up(count = 1)
|
39
|
+
move(line - count, column)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Keyboard
|
3
|
+
include Component
|
4
|
+
using CoreExt::Hash
|
5
|
+
|
6
|
+
def aliases
|
7
|
+
@aliases ||= {
|
8
|
+
"\e" => :escape,
|
9
|
+
ctrl_m: :enter,
|
10
|
+
dc: :delete,
|
11
|
+
ic: :insert,
|
12
|
+
npage: :page_down,
|
13
|
+
ppage: :page_up,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def codes
|
18
|
+
@codes ||= {
|
19
|
+
0 => [:ctrl, :space],
|
20
|
+
9 => :tab,
|
21
|
+
27 => :escape,
|
22
|
+
127 => :backspace,
|
23
|
+
263 => :backspace,
|
24
|
+
353 => [:shift, :tab],
|
25
|
+
527 => [:ctrl, :shift, :end],
|
26
|
+
532 => [:ctrl, :shift, :home],
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
@keys ||= terminal.keys.transform_keys do |key|
|
32
|
+
key.to_s.downcase.sub("key_", "").to_sym
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def listen
|
37
|
+
translate(terminal.input)
|
38
|
+
end
|
39
|
+
|
40
|
+
def translate(key)
|
41
|
+
return unless key
|
42
|
+
|
43
|
+
key = codes[key] if codes.key?(key)
|
44
|
+
key = keys.key(key) if keys.value?(key)
|
45
|
+
key = aliases[key] if aliases.key?(key)
|
46
|
+
|
47
|
+
case key
|
48
|
+
when 0..255 then key.chr.to_sym
|
49
|
+
when Array then key
|
50
|
+
else key.to_sym
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Mode
|
3
|
+
class Nano < Mode
|
4
|
+
bind :ctrl_c, Command::Quit
|
5
|
+
|
6
|
+
bind :up, Command::CursorUp
|
7
|
+
bind :down, Command::CursorDown
|
8
|
+
bind :left, Command::CursorLeft
|
9
|
+
bind :right, Command::CursorRight
|
10
|
+
|
11
|
+
bind :ctrl_p, Command::CursorUp
|
12
|
+
bind :ctrl_n, Command::CursorDown
|
13
|
+
bind :ctrl_b, Command::CursorLeft
|
14
|
+
bind :ctrl_f, Command::CursorRight
|
15
|
+
|
16
|
+
bind :ctrl_a, Command::CursorStart
|
17
|
+
bind :ctrl_e, Command::CursorEnd
|
18
|
+
|
19
|
+
bind :backspace, Command::Backspace
|
20
|
+
bind :ctrl_h, Command::Backspace
|
21
|
+
|
22
|
+
bind :ctrl_o, Command::WriteFile
|
23
|
+
|
24
|
+
bind :enter, Command::InsertLine
|
25
|
+
bind :tab, Command::InsertTab
|
26
|
+
|
27
|
+
bind(/^[[:print:]]$/, Command::InsertChar)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Mode
|
3
|
+
def self.bind(key, command = nil, &block)
|
4
|
+
keybindings[key] = command || block
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.keybindings
|
8
|
+
@keybindings ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def keybindings
|
12
|
+
self.class.keybindings
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve(key)
|
16
|
+
keybindings.each do |keybinding, command|
|
17
|
+
return command if keybinding === key
|
18
|
+
end
|
19
|
+
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class OperatingSystem
|
3
|
+
attr_reader :version
|
4
|
+
|
5
|
+
def initialize(version)
|
6
|
+
@version = version
|
7
|
+
end
|
8
|
+
|
9
|
+
def type
|
10
|
+
case version
|
11
|
+
when /cygwin/ then :Cygwin
|
12
|
+
when /bsd|linux/ then :Linux
|
13
|
+
when /darwin|mac/ then :Mac
|
14
|
+
when /mingw|mswin/ then :Windows
|
15
|
+
else :Unknown
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Reactor
|
3
|
+
include Component
|
4
|
+
|
5
|
+
def running?
|
6
|
+
!!@running
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
@running = true
|
11
|
+
render
|
12
|
+
listen
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
@running = false
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def listen
|
22
|
+
while running?
|
23
|
+
key = editor.keyboard.listen
|
24
|
+
next unless key
|
25
|
+
|
26
|
+
command = editor.mode.resolve(key)
|
27
|
+
next unless command
|
28
|
+
|
29
|
+
command.call(editor, key.to_s)
|
30
|
+
render
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def render
|
35
|
+
editor.window.render
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Terminal
|
3
|
+
include Component
|
4
|
+
include Curses
|
5
|
+
|
6
|
+
public :beep, :clear, :lines
|
7
|
+
|
8
|
+
def columns
|
9
|
+
cols
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_line
|
13
|
+
deleteln
|
14
|
+
end
|
15
|
+
|
16
|
+
def keys
|
17
|
+
self.class.constants.sort.grep(/^KEY/).reduce({}) do |hash, constant|
|
18
|
+
value = self.class.const_get(constant)
|
19
|
+
hash.update(constant => value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def input
|
24
|
+
getch
|
25
|
+
end
|
26
|
+
|
27
|
+
def move(*coords)
|
28
|
+
setpos(*coords)
|
29
|
+
end
|
30
|
+
|
31
|
+
def render
|
32
|
+
noecho # hide typed characters
|
33
|
+
nonl # disable newline translation
|
34
|
+
stdscr.keypad(true) # enable arrow keys
|
35
|
+
raw # enable all other keys
|
36
|
+
init_screen
|
37
|
+
start_color
|
38
|
+
yield
|
39
|
+
ensure
|
40
|
+
clear
|
41
|
+
close_screen
|
42
|
+
end
|
43
|
+
|
44
|
+
def write(string)
|
45
|
+
padded = string.ljust(columns)
|
46
|
+
addstr(padded)
|
47
|
+
end
|
48
|
+
|
49
|
+
def x
|
50
|
+
stdscr.curx
|
51
|
+
end
|
52
|
+
|
53
|
+
def y
|
54
|
+
stdscr.cury
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class TextEditor
|
2
|
+
class Window
|
3
|
+
extend Forwardable
|
4
|
+
include Component
|
5
|
+
|
6
|
+
def_delegators :state, :buffer, :cursor
|
7
|
+
|
8
|
+
def cache
|
9
|
+
@cache ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def file
|
13
|
+
config.files.first
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
buffer.each_line.with_index do |line, index|
|
18
|
+
if cache[index] != line
|
19
|
+
cache[index] = line
|
20
|
+
terminal.move(index, 0)
|
21
|
+
terminal.write(line)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
deleted_lines = cache.keys - (0...buffer.size).to_a
|
26
|
+
|
27
|
+
deleted_lines.each do |index|
|
28
|
+
cache.delete(index)
|
29
|
+
terminal.move(index, 0)
|
30
|
+
terminal.delete_line
|
31
|
+
end
|
32
|
+
|
33
|
+
terminal.move(*cursor.position)
|
34
|
+
end
|
35
|
+
|
36
|
+
def state
|
37
|
+
@state || update(Buffer.new(file), Cursor.new)
|
38
|
+
end
|
39
|
+
|
40
|
+
def update(buffer, cursor)
|
41
|
+
@state = State.new(buffer, cursor)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/text_editor.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require "logger"
|
3
|
+
require "optparse"
|
4
|
+
require "ostruct"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
require "bundler/setup"
|
8
|
+
require "curses"
|
9
|
+
|
10
|
+
require_relative "core_ext/hash"
|
11
|
+
require_relative "core_ext/pathname"
|
12
|
+
|
13
|
+
require_relative "text_editor/component"
|
14
|
+
|
15
|
+
require_relative "text_editor/buffer"
|
16
|
+
require_relative "text_editor/cursor"
|
17
|
+
require_relative "text_editor/keyboard"
|
18
|
+
require_relative "text_editor/operating_system"
|
19
|
+
require_relative "text_editor/reactor"
|
20
|
+
require_relative "text_editor/state"
|
21
|
+
require_relative "text_editor/terminal"
|
22
|
+
require_relative "text_editor/window"
|
23
|
+
|
24
|
+
require_relative "text_editor/clipboard"
|
25
|
+
require_relative "text_editor/clipboard/cygwin"
|
26
|
+
require_relative "text_editor/clipboard/linux"
|
27
|
+
require_relative "text_editor/clipboard/mac"
|
28
|
+
require_relative "text_editor/clipboard/unknown"
|
29
|
+
require_relative "text_editor/clipboard/windows"
|
30
|
+
|
31
|
+
require_relative "text_editor/command"
|
32
|
+
require_relative "text_editor/command/backspace"
|
33
|
+
require_relative "text_editor/command/quit"
|
34
|
+
require_relative "text_editor/command/cursor_down"
|
35
|
+
require_relative "text_editor/command/cursor_end"
|
36
|
+
require_relative "text_editor/command/cursor_left"
|
37
|
+
require_relative "text_editor/command/cursor_right"
|
38
|
+
require_relative "text_editor/command/cursor_start"
|
39
|
+
require_relative "text_editor/command/cursor_up"
|
40
|
+
require_relative "text_editor/command/insert_char"
|
41
|
+
require_relative "text_editor/command/insert_line"
|
42
|
+
require_relative "text_editor/command/insert_tab"
|
43
|
+
require_relative "text_editor/command/resolver"
|
44
|
+
require_relative "text_editor/command/write_file"
|
45
|
+
|
46
|
+
require_relative "text_editor/configuration"
|
47
|
+
require_relative "text_editor/configuration/bootstrap"
|
48
|
+
require_relative "text_editor/configuration/dsl"
|
49
|
+
require_relative "text_editor/configuration/resolver"
|
50
|
+
|
51
|
+
require_relative "text_editor/mode"
|
52
|
+
require_relative "text_editor/mode/nano"
|
53
|
+
|
54
|
+
class TextEditor
|
55
|
+
extend Configuration::DSL
|
56
|
+
|
57
|
+
GEMSPEC = File.expand_path("../../text_editor.gemspec", __FILE__)
|
58
|
+
|
59
|
+
def initialize(args)
|
60
|
+
@args = args
|
61
|
+
end
|
62
|
+
|
63
|
+
def bootstrap
|
64
|
+
@bootstrap ||= Configuration::Bootstrap.new(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
def clipboard
|
68
|
+
@clipboard ||= Clipboard.new(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
def config
|
72
|
+
@config ||= Configuration.new(self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def gemspec
|
76
|
+
@gemspec ||= Gem::Specification.load(GEMSPEC)
|
77
|
+
end
|
78
|
+
|
79
|
+
def keyboard
|
80
|
+
@keyboard ||= Keyboard.new(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
def logger
|
84
|
+
@logger ||= Logger.new(config.log.file, *config.log.options).tap do |log|
|
85
|
+
log.level = config.log.level
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def mode
|
90
|
+
@mode ||= Mode::Nano.new
|
91
|
+
end
|
92
|
+
|
93
|
+
def os
|
94
|
+
@os ||= OperatingSystem.new(RbConfig::CONFIG["host_os"])
|
95
|
+
end
|
96
|
+
|
97
|
+
def reactor
|
98
|
+
@reactor ||= Reactor.new(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
def root
|
102
|
+
@root ||= Pathname.new(__FILE__).dirname.dirname
|
103
|
+
end
|
104
|
+
|
105
|
+
def start
|
106
|
+
bootstrap.configure(@args)
|
107
|
+
terminal.render { reactor.start }
|
108
|
+
end
|
109
|
+
|
110
|
+
def terminal
|
111
|
+
@terminal ||= Terminal.new(self)
|
112
|
+
end
|
113
|
+
|
114
|
+
def window
|
115
|
+
@window ||= Window.new(self)
|
116
|
+
end
|
117
|
+
|
118
|
+
def version
|
119
|
+
gemspec.version.to_s
|
120
|
+
end
|
121
|
+
end
|
data/log/.keep
ADDED
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe CoreExt::Hash do
|
4
|
+
using described_class
|
5
|
+
|
6
|
+
subject { { one: 1, two: 2 } }
|
7
|
+
|
8
|
+
describe "#transform_keys" do
|
9
|
+
it "transforms the keys" do
|
10
|
+
actual = subject.transform_keys(&:to_s)
|
11
|
+
expected = { "one" => 1, "two" => 2 }
|
12
|
+
expect(actual).to eq(expected)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe CoreExt::Pathname do
|
4
|
+
using described_class
|
5
|
+
|
6
|
+
subject { Pathname.new(file) }
|
7
|
+
|
8
|
+
describe "#safe_read" do
|
9
|
+
context "with an existing file" do
|
10
|
+
let(:file) { __FILE__ }
|
11
|
+
|
12
|
+
it "returns file contents" do
|
13
|
+
expected = File.read(file)
|
14
|
+
expect(subject.safe_read).to eq(expected)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "with a non existing file" do
|
19
|
+
let(:file) { "this-does-not-exist.txt " }
|
20
|
+
|
21
|
+
it "returns file contents" do
|
22
|
+
expect(subject.safe_read).to be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
if ENV["CODECLIMATE_REPO_TOKEN"]
|
2
|
+
require "codeclimate-test-reporter"
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
else
|
5
|
+
require "simplecov"
|
6
|
+
SimpleCov.start { add_filter("/vendor/bundle/") }
|
7
|
+
end
|
8
|
+
|
9
|
+
require File.expand_path("../../lib/text_editor", __FILE__)
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.filter_run :focus
|
13
|
+
config.raise_errors_for_deprecations!
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
end
|