vim-doge
vim-doge copied to clipboard
Update of existing documentation
Is your feature request related to a problem? Please describe. DoGe is great to generate the docblock for a function that doesn't have already one. But when the signature of the function changes then (for example adding or removing parameters), the docblock cannot be automatically updated.
Describe the solution you'd like
It would be very useful to hit <c-d>
again on the function to update the existing docblock. Missing parameters would be added at the right position in the docblock depending on their order in the signature of the function, and parameters removed from the function would be deleted in the docblock.
Hi,
I did have this version before I released DoGe publically and it worked well, yet there is no possibility to support every language I am currently supporting. The problem here is that languages like Lua has --
as a comment, so there is no differentiation between the start or end of a comment block. They basically use single-line comments.
Assume you have this initially:
-- This is my additional description
--
-- This is my new_function.
-- @param p1 This is p1.
-- @param p2 This is p2.
function new_function(p1, p2)
end
So the actual comment here that is generated by DoGe is this part:
-- This is my new_function.
-- @param p1 This is p1.
-- @param p2 This is p2.
But if you open op a buffer containing this it will replace the whole comment again. Also, if you've added descriptions the only thing I should replace is the things that have been added, deleted or changed and doing this is close to impossible for now, there are too many use-cases to take into account, so I won't fix this by myself since I wasn't able to support every language.
If there is someone who has a suggestion and a pull request I am happy to think with them, but for now it won't happen. Thanks for your submission.
Thank you very for your detailed answer.
That's great news to know that you already developed this feature before. It think it is a must have feature to make DoGe even better. I understand that it could not be supported for a few languages. But as it would perfectly work for other ones, I think it would be a real shame to penalize them just because a few languages could not be supported. I strongly encourage you to think about it. You could specify in the doc which languages are supported for this feature and explain quickly why a few languages are not.
Hope you change your mind :wink: :crossed_fingers:
Hi @kkoomen, is this feature supported for python ? As python docstrings are delimited by """
, the problem you mentionned above seems not to apply (as delimiters are explicits).
I would be really great if it is !
Something like this :
def my_func(arg1, arg2):
"""
A useful docstring
"""
print("That's useful")
Turns into that :
def my_func(arg1, arg2):
"""
A useful docstring
:param arg1: [TODO:description]
:type arg1: [TODO:type]
:param arg2: [TODO:description]
:type arg2: [TODO:type]
"""
print("That's useful")
Sorry that this is still not fixed. The problem I'm having is that I should be able to merge two multiline strings (doc blocks) together using a history algorithm that git has, but this is difficult to implement. I am trying to get this to work with git, since it's probably the best out there to merge anything. I've made a stackoverflow question as well.
If anyone could help out, feel free to.
I am hesitant to answer at stackoverflow. So here's my two cents -
-
git diff --patch --word-diff=porcelain file2 file1 > temp
-
python script.py temp file3
This is the best that I can do. What is basically does is, it does a word-diff using git
and outputs it to temp. script.py
parses that word-diff from temp, and the output is written to file3. file3 is created/overwritten.
Here's script.py
-
import sys
print(sys.argv)
if not len(sys.argv) == 3:
print("Please mention only two files, in-file and out-file")
sys.exit(1)
with open(sys.argv[1]) as file:
text = file.read()
text = text[text.index("@@", text.index("@@") + 2) + 2 :]
out_lines = []
split = text.split("~")
for index, string in enumerate(split):
_splitline = string.split("\n")
_splitline = _splitline[1:-1]
if len(_splitline) == 1:
out_lines.append(_splitline[0][1:])
else:
for _line in _splitline[1:]:
if _line.startswith("+"):
out_lines.append(_splitline[0][1:] + _line[1:])
for index, string in enumerate(out_lines):
out_lines[index] = string + "\n"
out_string = ""
for string in out_lines:
out_string += string
with open(sys.argv[2], "w+") as writefile:
writefile.write(out_string)
@subnut Thanks for your effort. I'll see what I can do this weekend. If this works for one case then I expect this to work for most or perhaps even all cases.
@subnut Right now I do have file1 and file2 like this (php files):
file1
/**
* [TODO:description]
*
* @param [TODO:type] $user [TODO:description]
*
* @return [TODO:type] [TODO:description]
*/
function test($user) {}
file2
/**
* Lorem ipsum dor sit amet lorem ipsum dor sit amet lorem ipsum dor sit amet
* lorem ipsum dor sit amet lorem ipsum dor sit amet lorem ipsum dor sit amet
* lorem ipsum dor sit amet lorem ipsum.
*
* @param User $user The user object.
*
* @return void
*/
function test($user) {}
When I run git diff --patch --word-diff=porcelain file2 file1
it outputs nothing.
When I run
git diff --patch --word-diff=porcelain file2 file1
it outputs nothing.
Cannot reproduce. See my GIF -
An updated script -
# new script
# only replaces [TODO:
import sys
print(sys.argv)
if not len(sys.argv) == 3:
print("Please mention only two files, in-file and out-file")
sys.exit(1)
with open(sys.argv[1]) as file:
text = file.read()
text = text[text.index("@@", text.index("@@") + 2) + 2 :]
out_lines = []
split = text.split("~")
for index, string in enumerate(split):
_splitline = string.split("\n")
_splitline = _splitline[1:-1]
if len(_splitline) == 1:
out_lines.append(_splitline[0][1:])
elif len(_splitline) == 2:
_line = _splitline[1]
if _line.startswith("+"):
out_lines.append(_splitline[0][1:] + _line[1:])
elif len(_splitline) == 3:
if _splitline[2].startswith("+[TODO:"):
out_lines.append(_splitline[0][1:] + _splitline[2][1:])
else:
for _line in _splitline[1:]:
out_lines.append(_splitline[0][1:] + _line[1:])
for index, string in enumerate(out_lines):
out_lines[index] = string + "\n"
out_string = ""
for string in out_lines:
out_string += string
with open(sys.argv[2], "w+") as writefile:
writefile.write(out_string)
I am going to explain the difference between the old script and the new script below....
For reference, here are the files -
file1
/**
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis sem ut
* felis imperdiet elementum. Etiam eu consequat felis. Suspendisse ac lectus
* vel lacus blandit sollicitudin at ac sapien. Donec scelerisque nisl id tellus
* faucibus tempor. Praesent accumsan turpis nisi.
*
* @param array $p1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Duis gravida nisi eget mollis semper. Class aptent taciti sociosqu ad litora.
* @param float $p2 Lorem ipsum dor sit amet.
* @param string $p3 (optional) Lorem ipsum dor sit amet.
* @param \Drupal\core\Entity\Node $p4 Lorem ipsum dolor sit amet, consectetur
* adipiscing elit. Mauris pharetra commodo dolor.
* @return mixed [TODO:description]
*/
file2
/**
* [TODO:description]
*
* @param array $myVar [TODO:description]
* @param float $p2 [TODO:description]
* @param [TODO:type] $p3 (optional) [TODO:description]
* @param \Drupal\core\Entity\Node $p4 [TODO:description]
* @param [TODO:type] $p5 [TODO:description]
* @return [TODO:type] [TODO:description]
*/
temp (ie. output of the diff)
diff --git a/file2 b/file1
index 04acf1d..712d4a2 100644
--- a/file2
+++ b/file1
@@ -1,10 +1,14 @@
/**
~
*
-[TODO:description]
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis sem ut
~
+ * felis imperdiet elementum. Etiam eu consequat felis. Suspendisse ac lectus
~
+ * vel lacus blandit sollicitudin at ac sapien. Donec scelerisque nisl id tellus
~
+ * faucibus tempor. Praesent accumsan turpis nisi.
~
*
~
* @param array
-$myVar [TODO:description]
+$p1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
~
+ * Duis gravida nisi eget mollis semper. Class aptent taciti sociosqu ad litora.
~
* @param float $p2
-[TODO:description]
+Lorem ipsum dor sit amet.
~
* @param
-[TODO:type]
+string
$p3 (optional)
-[TODO:description]
+Lorem ipsum dor sit amet.
~
* @param \Drupal\core\Entity\Node $p4
-[TODO:description]
+Lorem ipsum dolor sit amet, consectetur
~
*
-@param [TODO:type] $p5 [TODO:description]
+adipiscing elit. Mauris pharetra commodo dolor.
~
* @return
-[TODO:type]
+mixed
[TODO:description]
~
*/
~
Now here's file3
, i.e. output of the scripts -
Old script output
/**
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis sem ut
* felis imperdiet elementum. Etiam eu consequat felis. Suspendisse ac lectus
* vel lacus blandit sollicitudin at ac sapien. Donec scelerisque nisl id tellus
* faucibus tempor. Praesent accumsan turpis nisi.
*
* @param array $p1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Duis gravida nisi eget mollis semper. Class aptent taciti sociosqu ad litora.
* @param float $p2 Lorem ipsum dor sit amet.
* @param string
* @param Lorem ipsum dor sit amet.
* @param \Drupal\core\Entity\Node $p4 Lorem ipsum dolor sit amet, consectetur
* adipiscing elit. Mauris pharetra commodo dolor.
* @return mixed
*/
New script output
/**
* [TODO:description]
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis sem ut
* felis imperdiet elementum. Etiam eu consequat felis. Suspendisse ac lectus
* vel lacus blandit sollicitudin at ac sapien. Donec scelerisque nisl id tellus
* faucibus tempor. Praesent accumsan turpis nisi.
*
* @param array $myVar [TODO:description]
* @param array $p1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Duis gravida nisi eget mollis semper. Class aptent taciti sociosqu ad litora.
* @param float $p2 [TODO:description]
* @param float $p2 Lorem ipsum dor sit amet.
* @param \Drupal\core\Entity\Node $p4 [TODO:description]
* @param \Drupal\core\Entity\Node $p4 Lorem ipsum dolor sit amet, consectetur
* @param [TODO:type] $p5 [TODO:description]
* adipiscing elit. Mauris pharetra commodo dolor.
*/
Difference
diff --git a/file3.old b/file3
index 78a1bbd..5d4e80e 100644
--- a/file3.old
+++ b/file3
@@ -1,15 +1,17 @@
/**
+ * [TODO:description]
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis sem ut
* felis imperdiet elementum. Etiam eu consequat felis. Suspendisse ac lectus
* vel lacus blandit sollicitudin at ac sapien. Donec scelerisque nisl id tellus
* faucibus tempor. Praesent accumsan turpis nisi.
*
+ * @param array $myVar [TODO:description]
* @param array $p1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Duis gravida nisi eget mollis semper. Class aptent taciti sociosqu ad litora.
+ * @param float $p2 [TODO:description]
* @param float $p2 Lorem ipsum dor sit amet.
- * @param string
- * @param Lorem ipsum dor sit amet.
+ * @param \Drupal\core\Entity\Node $p4 [TODO:description]
* @param \Drupal\core\Entity\Node $p4 Lorem ipsum dolor sit amet, consectetur
+ * @param [TODO:type] $p5 [TODO:description]
* adipiscing elit. Mauris pharetra commodo dolor.
- * @return mixed
*/
Sorry, there's a mistake in the updated script, please wait...
When I run
git diff --patch --word-diff=porcelain file2 file1
it outputs nothing.Cannot reproduce. See my GIF -
You're showing me here file1.php
and file2.php
but the actual command is using file1
and file2
instead of file1.php
and file2.php
.
Besides that part, I can get the diff if I am running git
inside a folder without a .git
folder. I used to run this in my vim-doge repo but that doesn't work. Can this be fixed?
Adding --no-index
fixes it and thus can be run in existing repo: git diff --patch --no-index --word-diff=porcelain file2 file1
@subnut Perhaps git merge-file might be useful. I really prefer to use the git merging algorithm. The logic I'm looking for is like this:
When generating a comment, replace the current one with the new one. When there's a conflict, just generate a new comment and insert the new comment, leaving the current one unchanged.
@kkoomen Give me some examples in this format -
- old_file contents
- new_file contents
- expected result
One example is in StackOverflow, I just need another example
You can test against this heavy python example:
file1 (current docblock)
def myFunc(p1: Callable[[int], None] = False, p2: Callable[[int, Exception], None] = {}) -> Callable[[int, Exception], None]:
"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec pulvinar eros. Aliquam erat volutpat. Praesent odio ligula, viverra ac imperdiet quis, vestibulum nec urna. Praesent rhoncus libero in purus.
:param p1 Callable[[int], None]: Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Sed nec pulvinar eros. Aliquam erat volutpat. Praesent
odio ligula, viverra ac imperdiet quis, vestibulum nec urna. Praesent
rhoncus libero in purus.
:param p2 Callable[[int, Exception], None]: Something short.
:rtype Callable[[int, Exception], None]: Something that's a bit longer but
still expands over 2 lines or more, lorem ipsum dor sit amet.
"""
pass
file2 (updated version, aka incoming change)
def myFunc(newVarName: int) -> int:
"""
[TODO:description]
:param newVarName int: [TODO:description]
:rtype int: [TODO:description]
"""
Expected result:
def myFunc(newVarName: int) -> int:
"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec pulvinar eros. Aliquam erat volutpat. Praesent odio ligula, viverra ac imperdiet quis, vestibulum nec urna. Praesent rhoncus libero in purus.
:param newVarName int: Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Sed nec pulvinar eros. Aliquam erat volutpat. Praesent
odio ligula, viverra ac imperdiet quis, vestibulum nec urna. Praesent
rhoncus libero in purus.
:rtype int: Something that's a bit longer but still expands over 2 lines or
more, lorem ipsum dor sit amet.
"""
pass
I'm doing this "expected result" based on how merging works. Ideally, to me, it should only preserve documentation if the p1
is still named p1
. If it's a different name then it should be a new [TODO: ...]
again, but that's something that could be thought about later (if possible)
Also show me your ideal result (for both, this example and the example in StackOverflow)
Perhaps the example I showed above is the ideal result for the majority. I am not sure about the most ideal behavior personally. It's something me and others have to experience and feel overtime. Let's do as above for now and if needed, we can make adjustments later. Being able to merge would be really nice already.
Hmm... let me see.... I may need upto a month to get something usable... I am going to be busy for 2 weeks. Feel free to consider alternatives.