cowrite 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92022a9db5707f4dae9c95807e6eb39b813056ea3b39c252d3f65aa67d62acf5
4
- data.tar.gz: 5b18e63cc172da86b5dba8d098510a00bb7c888fd2560f3f6f38a007f77c2aa5
3
+ metadata.gz: '0802510583d99ef115f4b8b21bcbf2ecb6d9924f0b8da3e5e494c47c74e7f5f3'
4
+ data.tar.gz: 591ba65a82edf2263336d8fe1cc1114c0462eac8138d0d587160187e6ea72b52
5
5
  SHA512:
6
- metadata.gz: 8b7560a50a193d66dd3208786deeb95638a67517c9cd630377ac8b3653f262f112f3b93e8ffcf820ef1b604661725bf2f0208c3891daa16abe2078f9f3374f37
7
- data.tar.gz: dcb4ee5bbb99036cdd506425102c905d7dc22ecedeed3125b02e08d700b7d35dc766247ac4827d30b01372bde42afec7a7004c76ebf44682e5d509c6f30eeb1e
6
+ metadata.gz: 7c5af9c56e2198b2976af8137f984e99632d52978b1002639e5ab8c6e23e7094b8acef41865d75e04a6802d4463eda1cf041790b0ce91c2c890b47f5c7784c76
7
+ data.tar.gz: 32aa39788c1ea19c2acb3eb0af9ea836d2d0a54688eac498a915248b2b2446f6ee645cd0ed582572488190adf0dfd3eff53ad35a031906fc379ecda3a92ec360
data/lib/cowrite/cli.rb CHANGED
@@ -19,19 +19,21 @@ class Cowrite
19
19
  end
20
20
 
21
21
  def run(argv)
22
- abort "Use only first argument for prompt" if argv.size != 1 # TODO: remove
23
- prompt = ARGV[0]
22
+ argv, files = parse_argv(argv)
24
23
 
25
- files = find_files prompt
24
+ abort "Use only first argument for prompt" if argv.size != 1
25
+ prompt = argv[0]
26
+
27
+ files = find_files prompt if files.empty?
26
28
 
27
29
  # prompting on main thread so we can go 1-by-1
28
30
  finish = lambda do |file, i, diff|
29
31
  # ask user if diff is fine (TODO: add a "no" option and re-prompt somehow)
30
32
  prompt "Diff for #{file}:\n#{color_diff(diff)}Apply diff to #{file}?", ["yes"]
31
33
 
32
- with_content_in_file("#{diff.strip}\n") do |path|
34
+ with_content_in_file(diff) do |path|
33
35
  # apply diff (force sus changes, do not make backups)
34
- cmd = "patch -f --posix #{file} < #{path}"
36
+ cmd = "patch --posix #{file} < #{path}"
35
37
  out = `#{cmd}`
36
38
  return if $?.success?
37
39
 
@@ -81,15 +83,21 @@ class Cowrite
81
83
  # prompt user with questions and answers until they pick one of them
82
84
  # - supports replying with the first letter of the answer
83
85
  # - supports enter for yes
86
+ # - when not interactive assume yes
84
87
  def prompt(question, answers)
85
- colored_answers = answers.map { |a| color(:underline, a[0]) + a[1...] }.join("/")
86
- loop do
87
- read = prompt_freeform "#{color_last_line(QUESTION_COLOR, question)} [#{colored_answers}]", color: :none
88
- read = "yes" if read == "" && answers.include?("yes")
89
- return read if answers.include?(read)
90
- if (ai = answers.map { |a| a[0] }.index(read))
91
- return answers[ai]
88
+ if $stdin.tty?
89
+ colored_answers = answers.map { |a| color(:underline, a[0]) + a[1...] }.join("/")
90
+ loop do
91
+ read = prompt_freeform "#{color_last_line(QUESTION_COLOR, question)} [#{colored_answers}]", color: :none
92
+ read = "yes" if read == "" && answers.include?("yes")
93
+ return read if answers.include?(read)
94
+ if (ai = answers.map { |a| a[0] }.index(read))
95
+ return answers[ai]
96
+ end
92
97
  end
98
+ else
99
+ return "yes" if answers.include?("yes")
100
+ abort "need answer but was not in interactive mode"
93
101
  end
94
102
  end
95
103
 
@@ -106,9 +114,9 @@ class Cowrite
106
114
  def color_diff(diff)
107
115
  modify_lines(diff) do |l, _, _|
108
116
  if l =~ /^-[^-]/
109
- color(:bg_light_green, l)
110
- elsif l =~ /^\+[^+]/
111
117
  color(:bg_light_red, l)
118
+ elsif l =~ /^\+[^+]/
119
+ color(:bg_light_green, l)
112
120
  else
113
121
  l
114
122
  end
@@ -138,5 +146,14 @@ class Cowrite
138
146
  def remove_shell_colors(string)
139
147
  string.gsub(/\e\[(\d+)(;\d+)*m/, "")
140
148
  end
149
+
150
+ # allow passing files after --
151
+ def parse_argv(argv)
152
+ if (dash_index = argv.index("--"))
153
+ [argv[0...dash_index], argv[dash_index + 1..]]
154
+ else
155
+ [argv, []]
156
+ end
157
+ end
141
158
  end
142
159
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  class Cowrite
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
data/lib/cowrite.rb CHANGED
@@ -37,6 +37,8 @@ class Cowrite
37
37
  # - tried "patch format" but that is often invalid
38
38
  # - tied "full fixed content" but that is always missing the fix
39
39
  # - need "ONLY" or it adds comments
40
+ # - tried asking for a diff but it's always in the wrong direction or has sublet bugs that make it unusable
41
+ content = File.read file
40
42
  prompt = <<~MSG
41
43
  Solve this prompt:
42
44
  ```
@@ -48,12 +50,17 @@ class Cowrite
48
50
  #{File.read file}
49
51
  ```
50
52
 
51
- Reply with ONLY the change in diff format.
53
+ Reply with ONLY:
54
+ - all changed content inside a single ``` block
55
+ - what range lines from the original content need to be removed as "LINES: <start>-<end>"
52
56
  MSG
53
57
  puts "prompt:#{prompt}" if ENV["DEBUG"]
54
58
  answer = send_to_openai(prompt)
55
59
  puts "answer:\n#{answer}" if ENV["DEBUG"]
56
- without_quotes(answer)
60
+ lines = answer.match(/LINES: (\d+)-(\d+)/)
61
+ answer.sub!(/.*\z/, "") # remove "LINES" line
62
+ section = without_quotes(answer).chomp # remove trailing newline since it always emits with an extra one
63
+ generate_diff content, section, from: Integer(lines[1]), to: Integer(lines[2])
57
64
  end
58
65
 
59
66
  private
@@ -63,6 +70,28 @@ class Cowrite
63
70
  answer.strip.sub(/\A```\S*\n(.*)```\z/m, "\\1")
64
71
  end
65
72
 
73
+ def generate_diff(original, changed, from:, to:)
74
+ Tempfile.create "cowrite-diff-a" do |a|
75
+ Tempfile.create "cowrite-diff-b" do |b|
76
+ a.write original
77
+ a.close
78
+
79
+ lines = original.split("\n", -1)
80
+ lines[(from - 1)..(to - 1)] = changed.split("\n", -1)
81
+ b.write lines.join("\n")
82
+ b.close
83
+
84
+ diff = `diff #{a.path} #{b.path}`
85
+ if $?.exitstatus == 0
86
+ raise "No diff found"
87
+ elsif $?.exitstatus != 1
88
+ raise "diff failed: #{diff}"
89
+ end
90
+ diff
91
+ end
92
+ end
93
+ end
94
+
66
95
  # def lines_from_file(file_path, line_number)
67
96
  # start_line = [line_number - @context, 1].max
68
97
  # end_line = line_number + @context
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cowrite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-23 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel