Applying Diffs
Closed this issue · 2 comments
refact-lsp smallcloudai/refact-lsp#226 gives you support for applying diffs to local files!
It's presented by 2 handlers:
v1/diff-apply
v1/diff-state
How to use it:
- call
v1/diff-state
to find out which chunks can be applied and which ones cannot. Disable in GUI those that cannot be applied - modify
apply
field in requests forv1/diff-apply
to set a desired state of chunks
to use v1/diff-apply
follow the format:
{
"apply": [true, false],
"chunks": [
{
"file_name": "some_file.txt",
"file_action": "edit",
"line1": 1,
"line2": 4,
"lines_remove": "...",
"lines_add": "...",
},
{
"file_name": "some_file.txt",
"file_action": "edit",
"line1": 9,
"line2": 10,
"lines_remove": "...",
"lines_add": "...",
}
]
}
Please note:
- len(apply) must be equal to len(chunks)
- chunks must be unchanged when calling
v1/diff-apply
, the only thing you should modify is theapply
array. - you can
apply
multiple chunks simultaneously. - it won't panic if you will apply what is already applied
apply
got a new behaviour:
apply
represents a desired state of chunks -- those which are true
will be applied, false
will be un-applied or untouched. For example, if you want to undo everything pass an array full of false
.
Output:
{
"fuzzy_results": [
{
"chunk_id": 0,
"fuzzy_n_used": 0
}
],
"state": [
1,
0,
0,
0,
0
]
}
fuzzy_results
is what you could ignore rn 😀, but here is what it is:
fuzzy_n_used
is a number -- by how many lines did we need to widen our search window to find the chunk in the text. When line1 and line2 match exactly the position in the file fuzzy_n_used
is equal to 0. The maximum fuzzy_n_used allowed is 10. fuzzy_n_used = 1 means, that the search window was made bigger by 1 line on top and 1 line on bottom.
state
on the other hand is quite useful!
state
is a list ofusize
(0 -- not applied, 1 -- applied or 2 -- failed to apply); len(state) is equal to len(chunks) from the input.- you can get the current state as a field in response of
v1/diff-apply
or when callingv1/diff-state
To use v1/diff-state
follow the format:
{
"chunks": [
{
"file_name": "some_file.txt",
"file_action": "edit",
"line1": 1,
"line2": 4,
"lines_remove": "...",
"lines_add": "...",
},
{
"file_name": "some_file.txt",
"file_action": "edit",
"line1": 9,
"line2": 10,
"lines_remove": "...",
"lines_add": "...",
}
]
}
Output:
{
"id": 16402438028794706325,
"state": [false, false, false, false],
"can_apply": [true, true, true, true]
}
state
says which chunks are applied and which aren't
can_apply
checks if chunks from request can be applied to the current state of the file.
A few words on how we store state in refact-lsp
:
we take chunks from the request and hash them into u64. That's why chunks shouldn't ever be modified during calls apply
otherwise we won't be able to get the state and will fail to apply/undo.
file_name
in chunks could be absolute or relative. If relative, refact-lsp
will try to complete it if it's present in index, otherwise it will try to respond with a meaningful error text
I think it's better to separate "apply": true from the chunks list, because it's not part of chat history.
Also, I'm not sure why we have integer in double quotes over there:
"chat_id": "1",
"message_id": "1",
Is it a string or an integer after all?
These handlers have been removed now it works through the patch api and the ide.