mawww / kakoune

mawww's experiment for a better code editor
http://kakoune.org
The Unlicense
9.91k stars 714 forks source link

Newline after an empty c-family // comment line removes the comment #919

Open rlofc opened 7 years ago

rlofc commented 7 years ago

Open an empty .cc file. Type // and press enter. The comment will be automatically removed by kakoune.

lenormf commented 7 years ago

That's not a bug, the commenting routine in the indent hook will remove empty comments to allow seamlessly writing a multiline comment and leave it by hitting the return key twice.

FreeFull commented 7 years ago

Could the same be done for other languages? It seems to happen with C, but not with Python, for example.

lenormf commented 7 years ago

The hook could be ported to other languages, I was just waiting for some time to test the hook in the field and fix the bugs it introduces.

rlofc commented 7 years ago

But sometimes (or many times) you do want an empty comment line. This enforces a certain behavior that while may work for some, does not work for many. I think pressing the return key should do what you would expect and that's creating a new comment line as many times as you want, even if these are empy - and - if you choose to exit from comment mode, hit backspace once and get a fresh clean line.

lenormf commented 7 years ago

The point of this hook is to implement "smart" handling of comment blocks, and since inserting empty comments is a rather unconventional practice I chose not to take it into account for the sake of not executing a hundred regular expressions to handle all cases.

mawww commented 7 years ago

Hum, thinking of it, documentation comments of the form

// brief description
//
// long description spanning
// multiple lines

Are pretty common, arent they ?

lenormf commented 7 years ago

The hook expects comment blocks to be within the usual /* and */ comment block characters. It's generally complicated to handle all cases without using many exec calls, so I had to make choices unfortunately.

mawww commented 7 years ago

After working a bit on #918 I am starting to think we should move these pretty smart comment copy logic in their own script, and not enable them by default.

Something like 'autocomment.kak' providing a command doing the /*...*/ start auto insert, and another command doing the // prefix autoinsert (actually, we could use commenting.kak option values for the prefix).

The user could then opt-in by adding a hook running these commands on InsertChar '\n'

lenormf commented 7 years ago

I was in the process of refactoring that hook as well, specifically to remove the logic that handles insertions in the middle of a comments block. This hook still has bugs and isn't even working perfectly well, so I think we should assume that the newline is inserted at the end of a command block (handling continuous typing rather than any kind of edition) to get rid of a few try/catch/exec calls.

And then eventually handle smart logic in a seperate file, but the functions in there are going to be ugly.

fsub commented 6 years ago

I'm regularly writing empty line comments. Automatic removal is really pesky. Now I'm using a modified version of c-family.kak which does not implement this behavior.

mawww commented 6 years ago

@fsub That issue got a bit forgotten, but it should be fixed for sure.

lenormf commented 6 years ago

Is that issue still occurring?

fsub commented 6 years ago

@lenormf Yes. As a workaround I'm using the following local modification:

--- c-family.kak.orig   2018-05-19 14:50:20.000000000 +0200
+++ c-family.kak.mine   2018-05-19 15:17:25.000000000 +0200
@@ -77,6 +77,9 @@
     try %[ execute-keys -itersel -draft hm<a-x>B<a-x><a-k>\A\h*(class|struct|union|enum)<ret> a\;<esc> ]
 ]

+declare-option -docstring %{control whether empty line comments should be kept or deleted} \
+    bool c_family_keep_empty_line_comments no
+
 define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel -draft %[
     execute-keys \;
     try %[
@@ -84,10 +87,19 @@
             # copy the commenting prefix
             execute-keys -save-regs '' k <a-x>1s^\h*(//+\h*)<ret> y
             try %[
-                # if the previous comment isn't empty, create a new one
-                execute-keys <a-x><a-K>^\h*//+\h*$<ret> j<a-x>s^\h*<ret>P
+                %sh{
+                    case "${kak_opt_c_family_keep_empty_line_comments}" in
+                        false|no)
+                            # select the previous line; fail if it represents an empty comment
+                            echo 'execute-keys <a-x><a-K>^\h*//+\h*$<ret>'
+                            ;;
+                        *);;
+                    esac
+                }
+                # paste the commenting prefix
+                execute-keys j<a-x>s^\h*<ret>P
             ] catch %[
-                # if there is no text in the previous comment, remove it completely
+                # remove the previous comment
                 execute-keys d
             ]
         ]
daboross commented 5 years ago

Here's an updated patch which completely removes the "remove empty comment lines" feature:

diff --git a/rc/filetype/c-family.kak b/rc/filetype/c-family.kak
index b985a15c..ce62a786 100644
--- a/rc/filetype/c-family.kak
+++ b/rc/filetype/c-family.kak
@@ -141,13 +141,8 @@ define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel
         evaluate-commands -draft -save-regs '/"' %[
             # copy the commenting prefix
             execute-keys -save-regs '' k <a-x>1s^\h*(//+\h*)<ret> y
-            try %[
-                # if the previous comment isn't empty, create a new one
-                execute-keys <a-x><a-K>^\h*//+\h*$<ret> j<a-x>s^\h*<ret>P
-            ] catch %[
-                # if there is no text in the previous comment, remove it completely
-                execute-keys d
-            ]
+            # create a new comment matching the previous line
+            execute-keys j<a-x>s^\h*<ret>P
         ]
     ]
     try %[
@@ -167,13 +162,8 @@ define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel
                 execute-keys -draft j<a-x><a-k>^\h+\*<ret>
                 execute-keys -draft i*<space><esc>
             ] catch %[
-                try %[
-                    # if the previous line is an empty comment line, close the comment scope
-                    execute-keys -draft k<a-x><a-k>^\h+\*\h+$<ret> <a-x>1s\*(\h*)<ret>c/<esc>
-                ] catch %[
-                    # if the previous line is a non-empty comment line, add a star
-                    execute-keys -draft i*<space><esc>
-                ]
+                # if the previous line is a comment line, add a star
+                execute-keys -draft i*<space><esc>
             ]
         ]

When writing this, I noticed that the current behavior is to remove empty lines for both // and /* comments. I personally use // comments for doc-comments which include many breaks, but if the goal was allow /* doc comments, I think the current behavior is lacking there too.

hugomg commented 1 month ago

What's the proper way to install the modified c-family file? Where does it go inside the .config/kak?

krobelus commented 1 month ago

The best approach is to clone the repo, apply the changes, compile and add src/kak to your $PATH. Alternativley, use autoload