{"thread":{"id":"57489","subject":"[GSoC][PATCH] userdiff: Add diff driver for Kotlin lang and tests","startedAt":"2022-03-01T07:03:01Z","lastAt":"2022-03-13T21:36:30Z","messageCount":48,"participants":["Jaydeep P Das","Junio C Hamano","Ævar Arnfjörð Bjarmason","jaydeepjd.8914@gmail.com","Johannes Sixt","Jaydeep Das"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"449872","messageId":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":null,"subject":"[GSoC][PATCH] userdiff: Add diff driver for Kotlin lang and tests","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-01T07:02:25Z","receivedAt":"2022-03-01T07:03:01Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"This patch adds diff driver for kotlin lang and some test cases for it.\nAlso, modifies `Documentation/.gitattributes.txt` to state the same\n\n\n"},{"id":"449873","messageId":"20220301070226.2477769-2-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH] userdiff: Add diff driver for Kotlin lang and tests","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-01T07:02:26Z","receivedAt":"2022-03-01T07:03:21Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header.\n\nThis patch adds xfuncname regex and some respective\ntests for Kotlin language.\n\nAlso modifies `Documentation./gitattributes.txt` to state\nthe same.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt | 2 ++\n t/t4018/kotlin-class            | 5 +++++\n t/t4018/kotlin-enum-class       | 5 +++++\n t/t4018/kotlin-fun              | 5 +++++\n t/t4018/kotlin-inheritace-class | 5 +++++\n t/t4018/kotlin-inline-class     | 5 +++++\n t/t4018/kotlin-interface        | 5 +++++\n t/t4018/kotlin-nested-fun       | 9 +++++++++\n t/t4018/kotlin-public-class     | 5 +++++\n t/t4018/kotlin-sealed-class     | 5 +++++\n userdiff.c                      | 8 ++++++++\n 11 files changed, 59 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..94d06dc337 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..a6cc6dc3b7 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,14 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t /* fun, class, interface, declarations */\n+  \t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*[ \\t]*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n+\t \"|[-+*/<>%&^|=!]=\"\n+\t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"449889","messageId":"xmqqy21urpap.fsf@gitster.g","threadId":"57489","inReplyTo":"20220301070226.2477769-2-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: Add diff driver for Kotlin lang and tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-01T09:32:30Z","receivedAt":"2022-03-01T09:32:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jaydeep P Das <jaydeepjd.8914@gmail.com> writes:\n\n> Subject: Re: [PATCH] userdiff: Add diff driver for Kotlin lang and tests\n\n\"Add\" -> \"add\".  \"lang and tests\" -> \"language\".\n\n> The xfuncname pattern finds func/class declarations in diffs to\n> display as a hunk header.\n\nYes, but an entry for a language in userdiff.c consists of the\nfuncname pattern AND the word_regex.  And I think the patch is\nadding both, not just funcname pattern.\n\n> This patch adds xfuncname regex and some respective\n> tests for Kotlin language.\n>\n> Also modifies `Documentation./gitattributes.txt` to state\n> the same.\n\nSee Documenation/SubmittingPatches::[[imperative-mood]].\n\nBut it probably is better to leave these unsaid.  The patterns,\ntests and documentation updates go hand in hand.\n\n>  11 files changed, 59 insertions(+)\n>  create mode 100644 t/t4018/kotlin-class\n>  create mode 100644 t/t4018/kotlin-enum-class\n>  create mode 100644 t/t4018/kotlin-fun\n>  create mode 100644 t/t4018/kotlin-inheritace-class\n>  create mode 100644 t/t4018/kotlin-inline-class\n>  create mode 100644 t/t4018/kotlin-interface\n>  create mode 100644 t/t4018/kotlin-nested-fun\n>  create mode 100644 t/t4018/kotlin-public-class\n>  create mode 100644 t/t4018/kotlin-sealed-class\n>\n> diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\n> index a71dad2674..94d06dc337 100644\n> --- a/Documentation/gitattributes.txt\n> +++ b/Documentation/gitattributes.txt\n> @@ -829,6 +829,8 @@ patterns are available:\n>  \n>  - `java` suitable for source code in the Java language.\n>  \n> +- `kotlin` suitable for source code in the Kotlin language\n> +\n>  - `markdown` suitable for Markdown documents.\n\nThe entries before and after this new one both end with a full stop,\nand this new entry should do the same.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..a6cc6dc3b7 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,14 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t /* fun, class, interface, declarations */\n> +  \t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*[ \\t]*)$\",\n\nWith the three keywords clearly visible in the pattern, the comment\nlooks somewhat redundant.  I dunno.\n\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n> +\t \"|[-+*/<>%&^|=!]=\"\n> +\t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n\nThe latter half is word regex, which is tested in t4034 to at least\nensure that it is well formed.  We can also add t/t4034/$language/\nto see the patterns hit the word boundary as expected.\n\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n"},{"id":"449896","messageId":"220301.867d9e107u.gmgdl@evledraar.gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-2-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: Add diff driver for Kotlin lang and tests","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-01T09:37:21Z","receivedAt":"2022-03-01T09:38:51Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Mar 01 2022, Jaydeep P Das wrote:\n\n> The xfuncname pattern finds func/class declarations\n> in diffs to display as a hunk header.\n>\n> This patch adds xfuncname regex and some respective\n> tests for Kotlin language.\n>\n> Also modifies `Documentation./gitattributes.txt` to state\n> the same.\n>\n> Signed-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n> ---\n>  Documentation/gitattributes.txt | 2 ++\n>  t/t4018/kotlin-class            | 5 +++++\n>  t/t4018/kotlin-enum-class       | 5 +++++\n>  t/t4018/kotlin-fun              | 5 +++++\n>  t/t4018/kotlin-inheritace-class | 5 +++++\n>  t/t4018/kotlin-inline-class     | 5 +++++\n>  t/t4018/kotlin-interface        | 5 +++++\n>  t/t4018/kotlin-nested-fun       | 9 +++++++++\n>  t/t4018/kotlin-public-class     | 5 +++++\n>  t/t4018/kotlin-sealed-class     | 5 +++++\n>  userdiff.c                      | 8 ++++++++\n\nI didn't look at the regexes etc. at a glance, but this is missing the\ncorresponding tests for the word-diff part of the regexes. It would be\nnice to have those tests too.\n\nSee the t/t4034/ directory for that (and no, this whole setup isn't very\ndiscoverable, sorry!).\n"},{"id":"449918","messageId":"806840db-e353-860a-e7ec-a83e303b648c@gmail.com","threadId":"57489","inReplyTo":"220301.867d9e107u.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH] userdiff: Add diff driver for Kotlin lang and tests","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-01T10:27:49Z","receivedAt":"2022-03-01T10:27:58Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Thanks for the review. I will be submitting another patch with\nthe requested changes shortly.\n\nThanks,\nJaydeep.\n"},{"id":"449933","messageId":"20220301155431.2534136-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-01T15:54:31Z","receivedAt":"2022-03-01T15:54:56Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 +++++\n t/t4018/kotlin-enum-class       |  5 +++++\n t/t4018/kotlin-fun              |  5 +++++\n t/t4018/kotlin-inheritace-class |  5 +++++\n t/t4018/kotlin-inline-class     |  5 +++++\n t/t4018/kotlin-interface        |  5 +++++\n t/t4018/kotlin-nested-fun       |  9 +++++++++\n t/t4018/kotlin-public-class     |  5 +++++\n t/t4018/kotlin-sealed-class     |  5 +++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 33 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 16 ++++++++++++++++\n t/t4034/kotlin/pre              | 16 ++++++++++++++++\n userdiff.c                      |  7 +++++++\n 15 files changed, 124 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..80eea3e386\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,33 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index e8a199a..e6ebebb 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,16 +1,16 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<RED>0xabcdef<RESET><GREEN>) (0xaybcdef)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> shl <RED>b a<RESET><GREEN>y x<RESET> shr <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a and b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x xnd y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>,y\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..e6ebebb5e9\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,16 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xaybcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+x shl y x shr y\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x xnd y\n+x^y\n+x or y\n+x&&y\n+x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+x,y\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..e8a199adb0\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,16 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shl b a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b\n+a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a,y\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..f23f098f19 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,13 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*[ \\t]*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n+\t \"|[-+*/<>%&^|=!]=\"\n+\t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"449938","messageId":"xmqq8rttsic1.fsf@gitster.g","threadId":"57489","inReplyTo":"20220301155431.2534136-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-01T17:17:34Z","receivedAt":"2022-03-01T17:17:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jaydeep P Das <jaydeepjd.8914@gmail.com> writes:\n\n> diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\n> index a71dad2674..4b36d51beb 100644\n> --- a/Documentation/gitattributes.txt\n> +++ b/Documentation/gitattributes.txt\n> @@ -829,6 +829,8 @@ patterns are available:\n>  \n>  - `java` suitable for source code in the Java language.\n>  \n> +- `kotlin` suitable for source code in the Kotlin language.\n> +\n>  - `markdown` suitable for Markdown documents.\n>  \n>  - `matlab` suitable for source code in the MATLAB and Octave languages.\n\nI do not speak the language, but hopefully those who do will find\nissues and help us correct them if there still are any.  The patch\norganization looks good.  Will queue.\n\nThanks.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..f23f098f19 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,13 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*[ \\t]*)$\",\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n> +\t \"|[-+*/<>%&^|=!]=\"\n> +\t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n"},{"id":"449951","messageId":"c59383e0-d549-d198-f358-18153f18d24b@gmail.com","threadId":"57489","inReplyTo":"xmqq8rttsic1.fsf@gitster.g","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-01T18:09:47Z","receivedAt":"2022-03-01T18:09:54Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Thanks for the review.\n\nI have some criticism regarding `t/t4018-diff-funcname.sh`.\n\nWhen any test fails, its verbose output is not \"verbose\" enough.\nFor example, If due to wrong xfuncname regex or wrong test, all of the\nfollowing hunk headers\n\n@@...@@\n@@...@@fun right(){\n@@...@@fun\n\nproduce the same verbose output:\n\n`not ok:....hunk header:[testfilename]`\n\nInitially, I had a difficult time to debug what was going wrong\nso as a temporary fix, I made `t/t4018-diff-funcname.sh` to\n`cat` out the hunk stored in `actual`.\n\n```\n# check each individual file\nfor i in $(git ls-files)\ndo\n\ttest_expect_success \"hunk header of file: $i\" \"\n\t\tgit diff -U1 $i >actual &&\n\t\techo 'hunk:' &&\n\t\tcat actual &&\n\t\techo &&\n\t\tgrep '@@ .* @@.*RIGHT' actual\n\t\"\ndone\n```\n\nIs there another proper way to make the test script produce\nthe hunk for each test?\n\nThanks,\nJaydeep.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"id":"449992","messageId":"5df2c9ce-b243-0173-befb-e13a6a74e387@kdbg.org","threadId":"57489","inReplyTo":"20220301155431.2534136-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-01T19:47:42Z","receivedAt":"2022-03-01T19:49:26Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 01.03.22 um 16:54 schrieb Jaydeep P Das:\n> diff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\n> new file mode 100644\n> index 0000000000..12186858cb\n> --- /dev/null\n> +++ b/t/t4018/kotlin-nested-fun\n> @@ -0,0 +1,9 @@\n> +class LEFT{\n> +\tclass CENTER{\n> +\t\tfun RIGHT(  a:Int){\n> +\t\t\t//comment\n> +\t\t\t//comment\n> +\t\t\tChangeMe\n> +\t\t}\n> +\t}\n> +}\n\nNice move to include a test with an indented key phrase. The t4018 test\ncases all look fine. I don't speek Kotlin, though, so...\n\n> diff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\n> new file mode 100644\n> index 0000000000..80eea3e386\n> --- /dev/null\n> +++ b/t/t4034/kotlin/expect\n> @@ -0,0 +1,33 @@\n> +<BOLD>diff --git a/pre b/post<RESET>\n> +<BOLD>index e8a199a..e6ebebb 100644<RESET>\n> +<BOLD>--- a/pre<RESET>\n> +<BOLD>+++ b/post<RESET>\n> +<CYAN>@@ -1,16 +1,16 @@<RESET>\n> +println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n> +<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<RED>0xabcdef<RESET><GREEN>) (0xaybcdef)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n> +[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n> +!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> shl <RED>b a<RESET><GREEN>y x<RESET> shr <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n> +<RED>a and b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x xnd y<RESET>\n> +<GREEN>x<RESET>^<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> or <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>&&<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>||<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>,y\n> diff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\n> new file mode 100644\n> index 0000000000..e6ebebb5e9\n> --- /dev/null\n> +++ b/t/t4034/kotlin/post\n> @@ -0,0 +1,16 @@\n> +println(\"Hello World?\")\n> +(1) (-1e10) (0xaybcdef) 'y'\n> +[x] x->y x.y\n> +!x x.inv() x*y x&y\n> +x*y x/y x%y\n> +x+y x-y\n> +x shl y x shr y\n> +x<y x<=y x>y x>=y\n> +x==y x!=y x===y\n> +x xnd y\n> +x^y\n> +x or y\n> +x&&y\n> +x||y\n> +x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n> +x,y\n> diff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\n> new file mode 100644\n> index 0000000000..e8a199adb0\n> --- /dev/null\n> +++ b/t/t4034/kotlin/pre\n> @@ -0,0 +1,16 @@\n> +println(\"Hello World!\\n\")\n> +1 -1e10 0xabcdef 'x'\n> +[a] a->b a.b\n> +!a a.inv() a*b a&b\n> +a*b a/b a%b\n> +a+b a-b\n> +a shl b a shr b\n> +a<b a<=b a>b a>=b\n> +a==b a!=b a===b\n> +a and b\n> +a^b\n> +a or b\n> +a&&b\n> +a||b\n> +a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n> +a,y\n\nI know you just copied an existing test case. But actually, it misses\nthe important parts of the word regex patterns. In particular, it only\ntests that a change of a to x is found, but does not test that the\noperators are not split into individual characters. Please have a look\nat my series 1cf93847c1ed~..386076ec92c7 and in particular 1cf93847c1ed\nto see what you actually want to test. For example, you could test a\nchange from a+=b to a-=b, i.e., that operators += and -= are not split\ninto +, -, and =.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..f23f098f19 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,13 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*[ \\t]*)$\",\n\nI would guess that the trailing [ \\t]* is pointless and always empty,\nbecause it is covered by the preceding .*, so you can remove it.\n\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n\nThe first part intends to match integers and floatingpoint numbers. Word\nregex can be loose. This one, however, is too loose. For example, it\ntreats  -e+2 as a single token, but that is actually a whole expression\nconsisting of several tokens and is not unlikely to occur in real code.\nSee also 350b87cd6585.\n\nI am pretty sure that, e.g., -1 and +2.5 are both two tokens each, i.e.,\nthe sign is not part of the number token.\n\nAlso, it looks like 3.0e5 is a floating point number; is 3.0E5 not?\n\n> +\t \"|[-+*/<>%&^|=!]=\"\n> +\t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n-- Hannes\n"},{"id":"450001","messageId":"1480c08e-940b-cc7e-9e92-5fe3b951d34a@kdbg.org","threadId":"57489","inReplyTo":"c59383e0-d549-d198-f358-18153f18d24b@gmail.com","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-01T19:59:10Z","receivedAt":"2022-03-01T19:59:18Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 01.03.22 um 19:09 schrieb jaydeepjd.8914@gmail.com:\n> When any test fails, its verbose output is not \"verbose\" enough.\n> For example, If due to wrong xfuncname regex or wrong test, all of the\n> following hunk headers\n> \n> @@...@@\n> @@...@@fun right(){\n> @@...@@fun\n> \n> produce the same verbose output:\n> \n> `not ok:....hunk header:[testfilename]`\n\nYou run\n\n  ./t4018-diff-funcname.sh -v -i\n\nwhich stops at the first failing test case. You get\n\nexpecting success of 4018.160 'hunk header: kotlin-interface':\n                git diff -U1 kotlin-interface >actual &&\n                grep '@@ .* @@.*RIGHT' actual\n\nnot ok 160 - hunk header: kotlin-interface\n#\n#                       git diff -U1 kotlin-interface >actual &&\n#                       grep '@@ .* @@.*RIGHT' actual\n#\n\nfrom which you see that you have to inspect the file actual:\n\n  less trash\\ directory.t4018-diff-funcname/actual\n\n-- Hannes\n"},{"id":"450057","messageId":"20220302064504.2651079-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[GSoC][PATCHv2] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T06:45:03Z","receivedAt":"2022-03-02T06:45:22Z","isPatch":false,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Thanks for the review.\nYes. As Johannes pointed out, the word_regex was very loose and did not\nproperly tokenise the code.\n\nI have fixed(and added tests) for the following things in this patch:\n\n+= or -= is not split into + = or - =\n-a or +a is split into 2 tokens(for each)\n\nSince kotlin supports `_` in between digits to improve readability,\ntherefore numbers like `100_000` are single tokens and not broken up\nby the regex in this patch.\n\nKotlin also does not support octal literals, and so the regex does not\nattempt to find it.\n\n"},{"id":"450058","messageId":"20220302064504.2651079-2-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220302064504.2651079-1-jaydeepjd.8914@gmail.com","subject":"[PATCH] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T06:45:04Z","receivedAt":"2022-03-02T06:45:36Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 +++++\n t/t4018/kotlin-enum-class       |  5 +++++\n t/t4018/kotlin-fun              |  5 +++++\n t/t4018/kotlin-inheritace-class |  5 +++++\n t/t4018/kotlin-inline-class     |  5 +++++\n t/t4018/kotlin-interface        |  5 +++++\n t/t4018/kotlin-nested-fun       |  9 +++++++++\n t/t4018/kotlin-public-class     |  5 +++++\n t/t4018/kotlin-sealed-class     |  5 +++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 35 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 19 ++++++++++++++++++\n t/t4034/kotlin/pre              | 19 ++++++++++++++++++\n userdiff.c                      |  8 ++++++++\n 15 files changed, 133 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..8acdc83bcc\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,35 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 884560d..7e136e2 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,19 +1,19 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+<RED>100000<RESET><GREEN>100_000<RESET>\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET><GREEN>y<RESET>\n+a<RED>+=<RESET><GREEN>-=<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> shl <RED>b a<RESET><GREEN>y x<RESET> shr <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>,y\n+-<RED>a<RESET><GREEN>x<RESET>+2\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..7e136e2bb4\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,19 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+100_000\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+a-=b\n+x*y x/y x%y\n+x+y x-y\n+x shl y x shr y\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y\n+x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+x,y\n+-x+2\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..884560d60f\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,19 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+100000\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a+=b\n+a*b a/b a%b\n+a+b a-b\n+a shl b a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b\n+a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a,y\n+-a+2\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..b92572b582 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,14 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[_]?[a-zA-Z][a-zA-Z0-9_]*\"\n+\t /*hexadecimal, integers and binary numbers*/\n+\t \"|(0x0F|0b)?[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n+\t /*match unary and binary operators*/\n+\t \"|[-+*/<>%&^|=!]*\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"450065","messageId":"34a2ad39-604c-4edd-ea1c-de1212fc506b@kdbg.org","threadId":"57489","inReplyTo":"20220302064504.2651079-2-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-02T08:00:34Z","receivedAt":"2022-03-02T08:00:46Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Added jc to Cc:.\n\nAm 02.03.22 um 07:45 schrieb Jaydeep P Das:\n> diff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\n> new file mode 100644\n> index 0000000000..8acdc83bcc\n> --- /dev/null\n> +++ b/t/t4034/kotlin/expect\n> @@ -0,0 +1,35 @@\n> +<BOLD>diff --git a/pre b/post<RESET>\n> +<BOLD>index 884560d..7e136e2 100644<RESET>\n> +<BOLD>--- a/pre<RESET>\n> +<BOLD>+++ b/post<RESET>\n> +<CYAN>@@ -1,19 +1,19 @@<RESET>\n> +println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n> +<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n> +<RED>100000<RESET><GREEN>100_000<RESET>\n\nThis test does not demonstrates that numbers do not end at an '_',\nbecause if it did end there, the change would be from the single token\n100000 to two tokens 100 and _000, and the mark-up would look exactly\nthe same as we see here, and would remain undiagnosed.\n\nInstead, write the pre-image as 100_000 and the post image as 200_000.\nThen the correct mark-up would be\n\n<RED>100_000<RESET><GREEN>200_000<RESET>\n\nand a bogus markup (that the test wants to diagnose) would look like\n\n<RED>100<RESET><GREEN>200<RESET>_000\n\n> +[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n> +!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET><GREEN>y<RESET>\n> +a<RED>+=<RESET><GREEN>-=<RESET>b\n\nOK, so you decided to check operator += and -=. But what about all the\nother multi-character operators?\n\n> +<RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> shl <RED>b a<RESET><GREEN>y x<RESET> shr <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> and <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>^<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> or <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>&&<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>||<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET>\n\nThis line is the best candidate to check many multi-character operators.\nFor example, the pre-image could read\n\na=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n\nand the post-image\n\na+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n\nbut there are more operators to check.\n\nPlease either make these changes or drop this t4034 test case, because\nin its current form it gives a false sense of security, IMHO.\n\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>,y\n> +-<RED>a<RESET><GREEN>x<RESET>+2\n\nWhat do you want to demonstrate with this new test case? If you want to\nshow that the + in +2 is not part of the number, then you must change,\nfor example, \"a+2\" to \"a+1\". If you change only the a to x, then we do\nnot know whether the +2 was regarded as one token or two.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..b92572b582 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,14 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[_]?[a-zA-Z][a-zA-Z0-9_]*\"\n\nAn underscore followed by a digit is not an identifier, but a number,\nright? Then this expression correctly does not match and the following\nexpression dedicated to numbers takes care of it. Good.\n\n> +\t /*hexadecimal, integers and binary numbers*/\n> +\t \"|(0x0F|0b)?[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\nWhat is this \"0x0F\"? Did you mean just \"0x\"? And what about prefixes 0X\nand 0B? Are they not used as prefixes for hex and binary numbers?\nMoreover, I do not see how a hex number 0xff would be matched as a\nsingle token.\n\n> +\t /*match unary and binary operators*/\n> +\t \"|[-+*/<>%&^|=!]*\"),\n\nDo not do this. There is an implicit single-character match that need\nnot be written down in the regex. List all multi-character operators\n(but not the single-character operators) like you did in earlier rounds.\nAs written, the \"++!=\" in an expression such as \"a++!=b++\" (which is not\nunlikely to be seen in real code) would be regarded as a single token.\n\nThe verb \"match\" in the comment does not match the style of the other\ncomments (drop the word), and please insert blanks between the comment\ndelimiters and the text.\n\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n-- Hannes\n"},{"id":"450071","messageId":"f16cf3aa-dbae-8645-1d59-a8d5639d22fc@gmail.com","threadId":"57489","inReplyTo":"34a2ad39-604c-4edd-ea1c-de1212fc506b@kdbg.org","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T09:09:23Z","receivedAt":"2022-03-02T09:09:35Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"> This test does not demonstrates that numbers do not end at an '_',\n> because if it did end there, the change would be from the single token\n> 100000 to two tokens 100 and _000, and the mark-up would look exactly\n> the same as we see here, and would remain undiagnosed.\n\nYes but numbers ending in `_` would be illegal syntax in Kotlin so the regex\nassumes that user is writing correct code.\n\n> Instead, write the pre-image as 100_000 and the post image as 200_000.\n> Then the correct mark-up would be\n> \n> <RED>100_000<RESET><GREEN>200_000<RESET>\n> \n> and a bogus markup (that the test wants to diagnose) would look like\n> \n> <RED>100<RESET><GREEN>200<RESET>_000\n\nRight. I will add that test too.\n\n\n> What is this \"0x0F\"? Did you mean just \"0x\"? \n\n`0x0F` indicates that its a hexadecimal literal in Kotlin.\n\n> And what about prefixes 0X\n> and 0B? Are they not used as prefixes for hex and binary numbers?\n> Moreover, I do not see how a hex number 0xff would be matched as a\n> single token.\n> \n> > +\t /*match unary and binary operators*/\n> > +\t \"|[-+*/<>%&^|=!]*\"),\n\nYes. I would make the changes.\n\n> Do not do this. There is an implicit single-character match that need\n> not be written down in the regex. List all multi-character operators\n> (but not the single-character operators) like you did in earlier rounds.\n> As written, the \"++!=\" in an expression such as \"a++!=b++\" (which is not\n> unlikely to be seen in real code) would be regarded as a single token.\n> \n> The verb \"match\" in the comment does not match the style of the other\n> comments (drop the word), and please insert blanks between the comment\n> delimiters and the text.\n> \n> >   PATTERNS(\"markdown\",\n> >   \t \"^ {0,3}#{1,6}[ \\t].*\",\n> >   \t /* -- */\n\nNoted.\n\n\nThanks,\nJaydeep.\n"},{"id":"450072","messageId":"e3996526-e3c7-7126-e8c6-4868c8e07f27@gmail.com","threadId":"57489","inReplyTo":"f16cf3aa-dbae-8645-1d59-a8d5639d22fc@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T09:28:38Z","receivedAt":"2022-03-02T09:28:48Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/2/22 2:39 PM, jaydeepjd.8914@gmail.com wrote:\n\n> `0x0F` indicates that its a hexadecimal literal in Kotlin.\n\n\nMy bad. It was wrong. Hexadecimals are prefixed with 0xFF. I will fix it.\n"},{"id":"450106","messageId":"20220302142608.2754709-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[GSoC][PATCHv3] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T14:26:07Z","receivedAt":"2022-03-02T14:26:42Z","isPatch":false,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Thanks Johannes for the review.\n\nThis patch hopefully fixes the problems you mentioned:\n\n- Hexadecimals, binary and numbers with `_` are considered a single\n  token\n\tPre                    Post\n    0xFF_EC_DE_5E          0xFF_E1_DE_5E\n\t0b100_000              0b100_100\n\t100_000                200_000\n\n  Even though a single character is changed in each of the above\n  numbers, the diffs would be produced as if they were single tokens\n\n\n- More tests added for \"proper\" multicharacter operators.\n  \n  Earlier regex would consider a++!=++b as 3 different tokens(a, ++!=++, b)\n  This patch matches the tokens properly into (a, ++, !=, ++, b)\n\n"},{"id":"450107","messageId":"20220302142608.2754709-2-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220302142608.2754709-1-jaydeepjd.8914@gmail.com","subject":"[PATCH] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-02T14:26:08Z","receivedAt":"2022-03-02T14:26:46Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 +++++\n t/t4018/kotlin-enum-class       |  5 +++++\n t/t4018/kotlin-fun              |  5 +++++\n t/t4018/kotlin-inheritace-class |  5 +++++\n t/t4018/kotlin-inline-class     |  5 +++++\n t/t4018/kotlin-interface        |  5 +++++\n t/t4018/kotlin-nested-fun       |  9 +++++++++\n t/t4018/kotlin-public-class     |  5 +++++\n t/t4018/kotlin-sealed-class     |  5 +++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 34 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 21 ++++++++++++++++++++\n t/t4034/kotlin/pre              | 21 ++++++++++++++++++++\n userdiff.c                      | 10 ++++++++++\n 15 files changed, 138 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..7062b67319\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,34 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 3cfa271..20d26cc 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,21 +1,21 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..20d26cca5f\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,21 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..3cfa271e37\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,21 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..bb701100c6 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,16 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[_]?[a-zA-Z][a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"450162","messageId":"fe93dfb2-7c0d-11cb-09a0-9ccc7fcc2507@kdbg.org","threadId":"57489","inReplyTo":"20220302142608.2754709-2-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-02T20:18:22Z","receivedAt":"2022-03-02T20:18:29Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 02.03.22 um 15:26 schrieb Jaydeep P Das:\n> diff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\n> new file mode 100644\n> index 0000000000..7062b67319\n> --- /dev/null\n> +++ b/t/t4034/kotlin/expect\n> @@ -0,0 +1,34 @@\n> +<BOLD>diff --git a/pre b/post<RESET>\n> +<BOLD>index 3cfa271..20d26cc 100644<RESET>\n> +<BOLD>--- a/pre<RESET>\n> +<BOLD>+++ b/post<RESET>\n> +<CYAN>@@ -1,21 +1,21 @@<RESET>\n> +println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n> +<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n> +[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n> +!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n> +a <RED>shr<RESET><GREEN>shl<RESET> b\n> +<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> and <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>^<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> or <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n> +a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n> +a<RED><<=<RESET><GREEN><=<RESET>b\n> +a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n> +<RED>a<RESET><GREEN>x<RESET>,y\n> +--a<RED>==<RESET><GREEN>!=<RESET>--b\n> +a++<RED>==<RESET><GREEN>!=<RESET>++b\n> +<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n\nMany of the a->x, b->y changes are redundant IMHO, but they do not hurt.\nThis looks good.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..bb701100c6 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,16 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[_]?[a-zA-Z][a-zA-Z0-9_]*\"\n> +\t /* hexadecimal and binary numbers */\n> +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> +\t /* integers and floats */\n> +\t \"|[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> +\t /* unary and binary operators */\n> +\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n\nSome of these sub-expressions match single-character operators, but that\ndoes not hurt.\n\nHow many tokens will the word-regex find in the expression X.e+200UL?\n.e+200UL is a single token. Also, X.Find consists of the three tokens X\n.F ind.\n\nIt's most easily fixed by requiring a digit before the fullstop. But if\nfloatingpoint numbers can begin with a fullstop, then we need a second\nexpression that requires a digit after a leading fullstop.\n\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n-- Hannes\n"},{"id":"450260","messageId":"76d46b15-f6c0-b8da-87e8-a992047b9a6a@gmail.com","threadId":"57489","inReplyTo":"fe93dfb2-7c0d-11cb-09a0-9ccc7fcc2507@kdbg.org","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-03T11:41:37Z","receivedAt":"2022-03-03T11:41:49Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"How about modifying the number match regex to:\n\n`[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n\nThe `[^a-zA-Z]` in the end would make sure to not match\nthe `.F` in `X.Find`.\n\nAdditionally, we can add another regex for matching just\nthe method calls:\n\n`[.][a-zA-Z()0-9]+`\n\nBoth of these changes would make word_regex match 2 tokens in\nX.Find() : X and .Find() (Here X can be any valid identifier name)\n\n\n> How many tokens will the word-regex find in the expression X.e+200UL?\n> .e+200UL is a single token. > It's most easily fixed by requiring a digit before the fullstop. But if\n> floatingpoint numbers can begin with a fullstop, then we need a second\n> expression that requires a digit after a leading fullstop.\n\nBut that syntax would be wrong. I tried making a condition like you said,\nbut it always ended up breaking something else(like breaking 2.e+200UL into 2, .e, + and 200UL)\n\nAlso, I realized I did a bit of mistake in the identifier regex.\nBoth _abc and __abc are valid identifiers. _3432, __3232 are valid identifiers too.(not numbers)\n\nThe previous regex matched only one `_`, so in the next patch,\nI plan to implement the following regex:\n\nIdentifier: `([_]*[a-zA-Z]|[_]+[0-9]+)[a-zA-Z0-9_]*`\n\nNumbers: `[0-9_.]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]`\n(It makes sure that in X.Find, .F is not matched )\n\nAdditionally, An extra regex for method calls:\n\n`[.][a-zA-Z()0-9]+`\n\nWhat do you think?\n\n\nThanks,\nJaydeep.\n\n"},{"id":"450292","messageId":"220303.865yov2csz.gmgdl@evledraar.gmail.com","threadId":"57489","inReplyTo":"76d46b15-f6c0-b8da-87e8-a992047b9a6a@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-03T16:54:26Z","receivedAt":"2022-03-03T16:58:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Mar 03 2022, Jaydeep Das wrote:\n\n> How about modifying the number match regex to:\n>\n> `[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n>\n> The `[^a-zA-Z]` in the end would make sure to not match\n> the `.F` in `X.Find`.\n>\n> Additionally, we can add another regex for matching just\n> the method calls:\n>\n> `[.][a-zA-Z()0-9]+`\n>\n> Both of these changes would make word_regex match 2 tokens in\n> X.Find() : X and .Find() (Here X can be any valid identifier name)\n>\n>\n>> How many tokens will the word-regex find in the expression X.e+200UL?\n>> .e+200UL is a single token. > It's most easily fixed by requiring a digit before the fullstop. But if\n>> floatingpoint numbers can begin with a fullstop, then we need a second\n>> expression that requires a digit after a leading fullstop.\n>\n> But that syntax would be wrong. I tried making a condition like you said,\n> but it always ended up breaking something else(like breaking 2.e+200UL into 2, .e, + and 200UL)\n>\n> Also, I realized I did a bit of mistake in the identifier regex.\n> Both _abc and __abc are valid identifiers. _3432, __3232 are valid identifiers too.(not numbers)\n>\n> The previous regex matched only one `_`, so in the next patch,\n> I plan to implement the following regex:\n>\n> Identifier: `([_]*[a-zA-Z]|[_]+[0-9]+)[a-zA-Z0-9_]*`\n>\n> Numbers: `[0-9_.]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]`\n> (It makes sure that in X.Find, .F is not matched )\n>\n> Additionally, An extra regex for method calls:\n>\n> `[.][a-zA-Z()0-9]+`\n>\n> What do you think?\n\nJust a small note on rx syntax> [.] can be handy to escape \".\" (but you\ncan also use \"\\\\.\", but that's arguably not as easy to read.\n\nBut there's no reason to use [_]* over just _*..\n\n(Also, I have an in-flight change to userdiff.c that would conflict, but\nI wonder if it wouldn't be handy to make the word_regex a \"struct\nuserdiff_funcname\". Then we could specify icase flags, which in this\ncase would make it a lot easier to read).\n\n"},{"id":"450297","messageId":"20220303181517.70682-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-03T18:15:17Z","receivedAt":"2022-03-03T18:15:43Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 +++++\n t/t4018/kotlin-enum-class       |  5 +++++\n t/t4018/kotlin-fun              |  5 +++++\n t/t4018/kotlin-inheritace-class |  5 +++++\n t/t4018/kotlin-inline-class     |  5 +++++\n t/t4018/kotlin-interface        |  5 +++++\n t/t4018/kotlin-nested-fun       |  9 ++++++++\n t/t4018/kotlin-public-class     |  5 +++++\n t/t4018/kotlin-sealed-class     |  5 +++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 37 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 24 +++++++++++++++++++++\n t/t4034/kotlin/pre              | 24 +++++++++++++++++++++\n userdiff.c                      | 12 +++++++++++\n 15 files changed, 149 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..f135eb2ab0\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,37 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index a569cfc..c4b213b 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,24 +1,24 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<RED>1 -1e10 <RESET><GREEN>(1) (-1e10) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a.b<RESET><GREEN>y x.y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n+a<RED>==<RESET><GREEN>===<RESET>b\n+<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n+X<RED>.fill()<RESET><GREEN>.find()<RESET>\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..c4b213b89e\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,24 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\n+a===b\n+_33.find(arr)\n+X.find()\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..a569cfcc6e\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,24 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\n+a==b\n+_32.find(arr)\n+X.fill()\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..b98961dd55 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,18 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"(_*[a-zA-Z]|_+[0-9])[a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[^_\\n][0-9_.]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]\"\n+\t /* method calls */\n+\t \"|[.][a-zA-Z()0-9]+\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"450299","messageId":"xmqqwnhaakdu.fsf@gitster.g","threadId":"57489","inReplyTo":"76d46b15-f6c0-b8da-87e8-a992047b9a6a@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-03T19:47:25Z","receivedAt":"2022-03-03T19:47:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jaydeep Das <jaydeepjd.8914@gmail.com> writes:\n\n> How about modifying the number match regex to:\n>\n> `[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n>\n> The `[^a-zA-Z]` in the end would make sure to not match\n> the `.F` in `X.Find`.\n\nDo we want to match \"foo.F<EOL>\"?  If requiring at least one\nnon-alpha after [fFlLuU]* is OK, then please ignore this message ;-)\n\nThanks.\n\n"},{"id":"450302","messageId":"c1298c9d-0f4a-40b8-b337-896f4d4777f3@kdbg.org","threadId":"57489","inReplyTo":"76d46b15-f6c0-b8da-87e8-a992047b9a6a@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-03T20:04:04Z","receivedAt":"2022-03-03T20:04:14Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 03.03.22 um 12:41 schrieb Jaydeep Das:\n> How about modifying the number match regex to:\n> \n> `[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n> \n> The `[^a-zA-Z]` in the end would make sure to not match\n> the `.F` in `X.Find`.\n\nNo, you cannot do that, because then in X.u+1 you have three tokens X\n.u+ 1, which you do not want, either.\n\n> Additionally, we can add another regex for matching just\n> the method calls:\n> \n> `[.][a-zA-Z()0-9]+`\n> \n> Both of these changes would make word_regex match 2 tokens in\n> X.Find() : X and .Find() (Here X can be any valid identifier name)\n\nWell, you can do that. But I would not do that if it is allowed to have\na blank between the fullstop and a method name.\n\n>> How many tokens will the word-regex find in the expression X.e+200UL?\n>> .e+200UL is a single token. > It's most easily fixed by requiring a\n>> digit before the fullstop. But if\n>> floatingpoint numbers can begin with a fullstop, then we need a second\n>> expression that requires a digit after a leading fullstop.\n> \n> But that syntax would be wrong. I tried making a condition like you said,\n> but it always ended up breaking something else(like breaking 2.e+200UL\n> into 2, .e, + and 200UL)\n> \n> Also, I realized I did a bit of mistake in the identifier regex.\n> Both _abc and __abc are valid identifiers. _3432, __3232 are valid\n> identifiers too.(not numbers)\n> \n> The previous regex matched only one `_`, so in the next patch,\n> I plan to implement the following regex:\n> \n> Identifier: `([_]*[a-zA-Z]|[_]+[0-9]+)[a-zA-Z0-9_]*`\n\nBut then you can use the regex you had in the first round:\n\n   [a-zA-Z_][a-zA-Z0-9_]*\n\n> \n> Numbers: `[0-9_.]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]`\n> (It makes sure that in X.Find, .F is not matched )\n> \n> Additionally, An extra regex for method calls:\n> \n> `[.][a-zA-Z()0-9]+`\n> \n> What do you think?\n\nHave a look at the regex in the cpp driver. I think we need something\nlike this:\n\n  /* integers floatingpoint numbers */\n  \"|[0-9][0-9_.]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n  /* floatingpoint numbers that begin with a decimal point */\n  \"|[.][0-9][0-9_]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n\nDrop the second option if numbers such as .5 are invalid syntax in Kotlin.\n\n-- Hannes\n"},{"id":"450350","messageId":"xmqqee3i4eso.fsf@gitster.g","threadId":"57489","inReplyTo":"20220303181517.70682-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-04T02:44:39Z","receivedAt":"2022-03-04T02:44:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jaydeep P Das <jaydeepjd.8914@gmail.com> writes:\n\n> Subject: Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.\n\n\"git format-patch --help\" and look for \"-v <n>\", perhaps.  This is\nthe fourth iteration, so [PATCH v4], I guess?\n\n"},{"id":"450356","messageId":"d38d18f5-f430-1f66-dff8-92b4a349b165@gmail.com","threadId":"57489","inReplyTo":"xmqqee3i4eso.fsf@gitster.g","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-04T05:16:30Z","receivedAt":"2022-03-04T05:16:40Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/4/22 8:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jaydeep P Das <jaydeepjd.8914@gmail.com> writes:\n> \n> > Subject: Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.\n> \n> \"git format-patch --help\" and look for \"-v <n>\", perhaps.  This is\n> the fourth iteration, so [PATCH v4], I guess?\n> \n\n\nYes. I think I forgot to fill in the subject so it was sent with the default.\nI didn't know format-patch allows to specify version numbers. I will check it out.\nAlso, In the next patch, should I do it as v4 or v5?\n\nThanks,\nJaydeep\n\n\n\n\n"},{"id":"450360","messageId":"d8d239bc-f5c3-4cac-91a1-16620f0b1f17@kdbg.org","threadId":"57489","inReplyTo":"xmqqee3i4eso.fsf@gitster.g","subject":"Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-04T07:25:54Z","receivedAt":"2022-03-04T07:26:05Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 04.03.22 um 03:44 schrieb Junio C Hamano:\n> Jaydeep P Das <jaydeepjd.8914@gmail.com> writes:\n> \n>> Subject: Re: [PATCH] userdiff: add builtin diff driver for Kotlin language.\n> \n> \"git format-patch --help\" and look for \"-v <n>\", perhaps.  This is\n> the fourth iteration, so [PATCH v4], I guess?\n\nNote though, that this iteration is a step in the wrong direction. Let's\nforget that it has been submitted. (I saw this submission only long\nafter I responded in the thread on the earlier round\nhttps://lore.kernel.org/git/c1298c9d-0f4a-40b8-b337-896f4d4777f3@kdbg.org/)\n\n-- Hannes\n"},{"id":"450386","messageId":"90596af6-0158-beb9-7fa7-9237e7cff4fb@gmail.com","threadId":"57489","inReplyTo":"c1298c9d-0f4a-40b8-b337-896f4d4777f3@kdbg.org","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Jaydeep Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-04T12:28:15Z","receivedAt":"2022-03-04T12:28:23Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/4/22 01:34, Johannes Sixt wrote:\n> Am 03.03.22 um 12:41 schrieb Jaydeep Das:\n>> How about modifying the number match regex to:\n>>\n>> `[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n>>\n>> The `[^a-zA-Z]` in the end would make sure to not match\n>> the `.F` in `X.Find`.\n  \n> No, you cannot do that, because then in X.u+1 you have three tokens X\n> .u+ 1, which you do not want, either.\n\nIf X is an integer here, then\n\nIn C/C++ 2.f is equivalent to 2.000000\nHowever in Kotlin 2.f is invalid syntax. 2.0f is valid.\n\nSo is implementing a proper regex for invalid syntax really\nnecessary?\n\n\n> But then you can use the regex you had in the first round:\n> \n>     [a-zA-Z_][a-zA-Z0-9_]*\n\nRight. I will change that.\n  \n>> Numbers: `[0-9_.]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]`\n>> (It makes sure that in X.Find, .F is not matched )\n>>\n>> Additionally, An extra regex for method calls:\n>>\n>> `[.][a-zA-Z()0-9]+`\n>>\n>> What do you think?\n> \n> Have a look at the regex in the cpp driver. I think we need something\n> like this:\n> \n>    /* integers floatingpoint numbers */\n>    \"|[0-9][0-9_.]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n>    /* floatingpoint numbers that begin with a decimal point */\n>    \"|[.][0-9][0-9_]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n\n\n> Drop the second option if numbers such as .5 are invalid syntax in Kotlin.\n.5 is valid syntax in Kotlin.\n\n--\nThanks,\nJaydeep.\n\n  \n\n\n\n"},{"id":"450397","messageId":"674822c0-583c-a5ca-6528-751777a24f99@kdbg.org","threadId":"57489","inReplyTo":"90596af6-0158-beb9-7fa7-9237e7cff4fb@gmail.com","subject":"Re: [PATCH] userdiff: add builtin driver for kotlin language","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-04T13:59:33Z","receivedAt":"2022-03-04T13:59:38Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 04.03.22 um 13:28 schrieb Jaydeep Das:\n> On 3/4/22 01:34, Johannes Sixt wrote:\n>> Am 03.03.22 um 12:41 schrieb Jaydeep Das:\n>>> How about modifying the number match regex to:\n>>>\n>>> `[0-9._]+([Ee][-+]?[0-9]+)?[fFlLuU]*[^a-zA-Z]` ?\n>>>\n>>> The `[^a-zA-Z]` in the end would make sure to not match\n>>> the `.F` in `X.Find`.\n>  \n>> No, you cannot do that, because then in X.u+1 you have three tokens X\n>> .u+ 1, which you do not want, either.\n> \n> If X is an integer here, then\n\nNo, I mean X literally, i.e., an identifier.\n\n> \n> In C/C++ 2.f is equivalent to 2.000000\n> However in Kotlin 2.f is invalid syntax. 2.0f is valid.\n> \n> So is implementing a proper regex for invalid syntax really\n> necessary?\n\nNo, that's not necessary. It can be assumed that invalid syntax does not\noccur. For this reason...\n\n>> Have a look at the regex in the cpp driver. I think we need something\n>> like this:\n>>\n>>    /* integers floatingpoint numbers */\n>>    \"|[0-9][0-9_.]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n\n... I propose this loose [0-9_.]* after the first digit, even though it\nwould match \"9.8_7._65\"; we can assume that this invalid token will not\noccur.\n\nBTW, make that [FfLlUl] near the end.\n\n>>    /* floatingpoint numbers that begin with a decimal point */\n>>    \"|[.][0-9][0-9_]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n> \n> \n>> Drop the second option if numbers such as .5 are invalid syntax in\n>> Kotlin.\n> .5 is valid syntax in Kotlin.\n\nOK, then we need this second branch, which ensures that there is a digit\nafter the fullstop.\n\n-- Hannes\n"},{"id":"450488","messageId":"20220305094004.250570-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH v4] userdiff: add builtin diff driver for Kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-05T09:40:04Z","receivedAt":"2022-03-05T09:40:17Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 +++++\n t/t4018/kotlin-enum-class       |  5 +++++\n t/t4018/kotlin-fun              |  5 +++++\n t/t4018/kotlin-inheritace-class |  5 +++++\n t/t4018/kotlin-inline-class     |  5 +++++\n t/t4018/kotlin-interface        |  5 +++++\n t/t4018/kotlin-nested-fun       |  9 ++++++++\n t/t4018/kotlin-public-class     |  5 +++++\n t/t4018/kotlin-sealed-class     |  5 +++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 39 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 26 ++++++++++++++++++++++\n t/t4034/kotlin/pre              | 26 ++++++++++++++++++++++\n userdiff.c                      | 12 ++++++++++\n 15 files changed, 155 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..228da3e95e\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,39 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 0c2a5a8..a9e7b41 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,26 +1,26 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a.b<RESET><GREEN>y x.y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n+a<RED>==<RESET><GREEN>===<RESET>b\n+<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n+X<RED>.fill()<RESET><GREEN>.find()<RESET>\n+X<RED>.u<RESET><GREEN>.f<RESET>+1\n+X.u<RED>-<RESET><GREEN>+<RESET>2\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..a9e7b41631\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,26 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\n+a===b\n+_33.find(arr)\n+X.find()\n+X.f+1\n+X.u+2\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..0c2a5a82b3\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,26 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\n+a==b\n+_32.find(arr)\n+X.fill()\n+X.u+1\n+X.u-2\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..24821a0f69 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,18 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[0-9][0-9_.]*([Ee][-+]?[0-9]+)?[fFlL]*\"\n+\t /* method calls */\n+\t \"|[.][a-zA-Z()0-9]+\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"450494","messageId":"4118762b-e2f1-4f77-68f3-e61cbe65aff7@kdbg.org","threadId":"57489","inReplyTo":"20220305094004.250570-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH v4] userdiff: add builtin diff driver for Kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-05T14:17:17Z","receivedAt":"2022-03-05T14:17:24Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 05.03.22 um 10:40 schrieb Jaydeep P Das:\n> +<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n> +X<RED>.fill()<RESET><GREEN>.find()<RESET>\n> +X<RED>.u<RESET><GREEN>.f<RESET>+1\n> +X.u<RED>-<RESET><GREEN>+<RESET>2\n\nNice move to include these new tests!\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..24821a0f69 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t /* hexadecimal and binary numbers */\n> +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> +\t /* integers and floats */\n> +\t \"|[0-9][0-9_.]*([Ee][-+]?[0-9]+)?[fFlL]*\"\n\nGood!\n\n> +\t /* method calls */\n> +\t \"|[.][a-zA-Z()0-9]+\"\n\nThis matches both .empty() as well as .125, but only the .5e part of\n.5e-3 and only the .find(x part of .find(x/2). Is that intended?\n\nI find the desire to have method calls as an entire token a bit strange.\nIn other languages, the last expression part is actually split into many\ntokens: . find ( x / 2 ).\n\nBTW, I'm in no way saying that this must be changed (personally I do not\ncare at all as I'm not writing Kotlin), so if you say that is how people\nwant Kotlin code to be split with --word-diff, I will believe you.\n\n> +\t /* unary and binary operators */\n> +\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n\nIs the part\n\n\t \"|\\\\|->\\\\*?|\"\n\nactually meant to be something else? Does Kotlin have the tokens \"|->\"\nand \"|->*\"?\n\nA final minor nit: There is \"|&&?|[|]?\\\\||\" that could just be\n\"|&&|\\\\|\\\\||\" (remember: single character operators are matched implicitly).\n\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n-- Hannes\n"},{"id":"450498","messageId":"6481bd49-eac9-9ebe-3d19-866107378f81@gmail.com","threadId":"57489","inReplyTo":"4118762b-e2f1-4f77-68f3-e61cbe65aff7@kdbg.org","subject":"Re: [PATCH v4] userdiff: add builtin diff driver for Kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-05T19:18:00Z","receivedAt":"2022-03-05T19:18:09Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n> > +\t /* method calls */\n> > +\t \"|[.][a-zA-Z()0-9]+\"\n> \n> This matches both .empty() as well as .125, but only the .5e part of\n> .5e-3 and only the .find(x part of .find(x/2). Is that intended?\n\nOh. It completely missed my mind. Anyways, that method call regex is better gone.\nFor matching these,\nMaybe we could just use cpp's regex for floating numbers starting with decimal point:\n\n\"|\\\\.[0-9][0-9]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n\nOr maybe, we can make the current regex for floats and integers a bit more loose:\n\n\"|[0-9.][0-9_.]*([Ee][*-]?[0-9]+)?[FfLl]*\" \n\nWhat do you think would be better?\n\n\n\n> I find the desire to have method calls as an entire token a bit strange.\n> In other languages, the last expression part is actually split into many\n> tokens: . find ( x / 2 ).\n> \n> BTW, I'm in no way saying that this must be changed (personally I do not\n> care at all as I'm not writing Kotlin), so if you say that is how people\n> want Kotlin code to be split with --word-diff, I will believe you.\n\nYes. The tokenisation does not make sense if its something like `X.find(2)`.\nI think I should remove it.\n\n\n> > +\t /* unary and binary operators */\n> > +\t \"|[-+*/<>%&^|=!]?=(=)?|--|\\\\+\\\\+|<<?=?|>>?=?|&&?|[|]?\\\\||\\\\|->\\\\*?|\\\\.\\\\*\"),\n> \n> Is the part\n> \n> \t \"|\\\\|->\\\\*?|\"\n> \n> actually meant to be something else? Does Kotlin have the tokens \"|->\"\n> and \"|->*\"?\n\nAh. yes. Kotlin does have \"->\" operator but not \"|->\". Also there are a few\nmore compound operators like \"..\" , \"!!\" etc which I forgot to add. I will add these in the next patch.\n  \n \n> A final minor nit: There is \"|&&?|[|]?\\\\||\" that could just be\n> \"|&&|\\\\|\\\\||\" (remember: single character operators are matched implicitly).\n> \n\nYes. Right.\n\n\n--\nThanks :]\nJaydeep\n"},{"id":"450499","messageId":"bee0dba1-e01c-4a2b-6a46-79361bfb3459@kdbg.org","threadId":"57489","inReplyTo":"6481bd49-eac9-9ebe-3d19-866107378f81@gmail.com","subject":"Re: [PATCH v4] userdiff: add builtin diff driver for Kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-05T22:17:56Z","receivedAt":"2022-03-05T22:18:03Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 05.03.22 um 20:18 schrieb jaydeepjd.8914@gmail.com:\n> Maybe we could just use cpp's regex for floating numbers starting with\n> decimal point:\n> \n> \"|\\\\.[0-9][0-9]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n\nYes, but with '_' permitted after the first digit:\n\n\t\"|\\\\.[0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n\n> \n> Or maybe, we can make the current regex for floats and integers a bit\n> more loose:\n> \n> \"|[0-9.][0-9_.]*([Ee][*-]?[0-9]+)?[FfLl]*\"\n> What do you think would be better?\n\nNo, that does not work, either, because it splits X.Find into X .F ind.\nI fixed that very problem with the cpp driver recently. We do need a\nseparate alternative for the floatingpoint numbers that start with a\ndecimal point.\n\n-- Hannes\n"},{"id":"450501","messageId":"20220306111539.336475-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-06T11:15:39Z","receivedAt":"2022-03-06T11:16:10Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 ++++\n t/t4018/kotlin-enum-class       |  5 ++++\n t/t4018/kotlin-fun              |  5 ++++\n t/t4018/kotlin-inheritace-class |  5 ++++\n t/t4018/kotlin-inline-class     |  5 ++++\n t/t4018/kotlin-interface        |  5 ++++\n t/t4018/kotlin-nested-fun       |  9 +++++++\n t/t4018/kotlin-public-class     |  5 ++++\n t/t4018/kotlin-sealed-class     |  5 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 42 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 29 +++++++++++++++++++++++\n t/t4034/kotlin/pre              | 29 +++++++++++++++++++++++\n userdiff.c                      | 12 ++++++++++\n 15 files changed, 164 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..d80e17d2c5\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,42 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 1db2197..ec0a891 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,29 +1,29 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n+a<RED>==<RESET><GREEN>===<RESET>b\n+a<RED>!!<RESET><GREEN>!=<RESET>b\n+<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n+X.<RED>fill<RESET><GREEN>find<RESET>()\n+X.<RED>u<RESET><GREEN>f<RESET>+1\n+X.u<RED>-<RESET><GREEN>+<RESET>2\n+a<RED>.<RESET><GREEN>..<RESET>b\n+a<RED>?.<RESET><GREEN>?:<RESET>b\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..ec0a8919e9\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,29 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\n+a===b\n+a!=b\n+_33.find(arr)\n+X.find()\n+X.f+1\n+X.u+2\n+a..b\n+a?:b\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..1db2197baa\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,29 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\n+a==b\n+a!!b\n+_32.find(arr)\n+X.fill()\n+X.u+1\n+X.u-2\n+a.b\n+a?.b\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..cd2155bbfe 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,18 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlL]*\"\n+\t /* floating point numbers beginning with decimal point */\n+\t \"|[.][0-9][0-9]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<?=?|>>?=?|&&|\\\\|[|]?|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"450515","messageId":"8799cd42-bb05-a827-187d-33fb03565f21@kdbg.org","threadId":"57489","inReplyTo":"20220306111539.336475-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-07T07:07:59Z","receivedAt":"2022-03-07T07:08:06Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 06.03.22 um 12:15 schrieb Jaydeep P Das:\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..cd2155bbfe 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t /* hexadecimal and binary numbers */\n> +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> +\t /* integers and floats */\n> +\t \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlL]*\"\n> +\t /* floating point numbers beginning with decimal point */\n> +\t \"|[.][0-9][0-9]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n\nI guess that the suffix u is intended to mark unsigned integers. So, I\nwould say that the alternatives [fFlL] and [fFlLuU] should be swapped.\n\nFurthermore, is it intentional that you do not recognize the '_' digit\nseparator in floating point numbers that begin with a decimal point?\n\n> +\t /* unary and binary operators */\n> +\t \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<?=?|>>?=?|&&|\\\\|[|]?|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n\nWhat is the justification that there is still \"|&&|\\\\|[|]?|\" instead of\n\"|&&|\\\\|\\\\||\" that I suggested (and I think I stressed that the point is\nthat single-character operators are matched elsewhere) and to which you\nsaid \"yes, right\"?\n\nAlso, the part \"|<<?=?|>>?=?|\" can match <, >, <=, and >=, all of which\nare matched by other expressions, so you could reduce it to \"|<<=|>>=|\",\nbecause that are the only tokens that they must match.\n\n-- Hannes\n"},{"id":"450758","messageId":"cf8a9316-c81e-2477-a565-1c38a168fc67@gmail.com","threadId":"57489","inReplyTo":"8799cd42-bb05-a827-187d-33fb03565f21@kdbg.org","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-08T16:54:47Z","receivedAt":"2022-03-08T16:54:56Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n> I guess that the suffix u is intended to mark unsigned integers. So, I\n> would say that the alternatives [fFlL] and [fFlLuU] should be swapped.\n\nOkay.\n\n> Furthermore, is it intentional that you do not recognize the '_' digit\n> separator in floating point numbers that begin with a decimal point?\n\nNo. I will fix it.\n\n> > +\t /* unary and binary operators */\n> > +\t \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<?=?|>>?=?|&&|\\\\|[|]?|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n> \n> What is the justification that there is still \"|&&|\\\\|[|]?|\" instead of\n> \"|&&|\\\\|\\\\||\" that I suggested (and I think I stressed that the point is\n> that single-character operators are matched elsewhere) and to which you\n> said \"yes, right\"?\n\nYes. Must have slipped my mind. Sorry.\n\n> Also, the part \"|<<?=?|>>?=?|\" can match <, >, <=, and >=, all of which\n> are matched by other expressions, so you could reduce it to \"|<<=|>>=|\",\n> because that are the only tokens that they must match.\n\nAlright.\n\nSo, the final regexes are these, right?: \n\n\n\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n\t /* hexadecimal and binary numbers */\n\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n\t /* integers and floats */\n\t \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\t /* floating point numbers beginning with decimal point */\n\t \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n\t /* unary and binary operators */\n\t \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<=|>>=|&&|[||]|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n\n\nThanks,\nJaydeep.\n\n\n\n"},{"id":"450766","messageId":"72aca675-4c65-36bf-1337-34b2d1f40bb4@kdbg.org","threadId":"57489","inReplyTo":"cf8a9316-c81e-2477-a565-1c38a168fc67@gmail.com","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-08T18:32:15Z","receivedAt":"2022-03-08T18:32:48Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 08.03.22 um 17:54 schrieb jaydeepjd.8914@gmail.com:\n> So, the final regexes are these, right?:\n\nNot quite.\n\n> \n>      \"[a-zA-Z_][a-zA-Z0-9_]*\"\n>      /* hexadecimal and binary numbers */\n>      \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n>      /* integers and floats */\n>      \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\nThis would not match 12.5 because you allow only a single digit before\nthe decimal point. Perhaps\n\n\t\"|[0-9][.0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\n>      /* floating point numbers beginning with decimal point */\n>      \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n>      /* unary and binary operators */\n>     \n> \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<=|>>=|&&|[||]|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n\n[||] does not work as you intend. A new suggestion: do not start with an\ninitial optional character in order to reduce the number of\nbacktrackings that the regular expression evaluation has to do. I would\nwrite this line as\n\n\t\"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n\nBTW which operators are handled by \"[?:.][.:]\"? I'm asking because you\nlist :: separatly that would also be matched by this sub-expression.\n\n-- Hannes\n"},{"id":"450991","messageId":"8d411f30-bfe9-ffbe-5ec5-1ae7b5c9588f@gmail.com","threadId":"57489","inReplyTo":"72aca675-4c65-36bf-1337-34b2d1f40bb4@kdbg.org","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-10T10:52:05Z","receivedAt":"2022-03-10T10:52:16Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Sorry for the late reply. \n\nOn 3/9/22 12:02 AM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 08.03.22 um 17:54 schrieb jaydeepjd.8914@gmail.com:\n> > So, the final regexes are these, right?:\n> \n> Not quite.\n> \n> >\n> >       \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> >       /* hexadecimal and binary numbers */\n> >       \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> >       /* integers and floats */\n> >       \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> \n> This would not match 12.5 because you allow only a single digit before\n> the decimal point. Perhaps\n> \n> \t\"|[0-9][.0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\nOkay. \n\n> >       /* floating point numbers beginning with decimal point */\n> >       \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlL]?\"\n> >       /* unary and binary operators */\n> >      \n> > \"|[-+*/<>%&^|=!]?==?|--|\\\\+\\\\+|<<=|>>=|&&|[||]|->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n> \n> [||] does not work as you intend. A new suggestion: do not start with an\n> initial optional character in order to reduce the number of\n> backtrackings that the regular expression evaluation has to do. I would\n> write this line as\n> \n> \t\"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|::|[?:.][.:]\"),\n> \n> BTW which operators are handled by \"[?:.][.:]\"? I'm asking because you\n> list :: separatly that would also be matched by this sub-expression.\n\nIt matches the following operators: `?:`, `?.`, `..` `::`. Although matching `::` is\nunnecessary since its matched before.\n\nhttps://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols\n\n\n \n\n"},{"id":"451037","messageId":"64677295-e7fd-ba4b-ce68-fe62132ca504@gmail.com","threadId":"57489","inReplyTo":"72aca675-4c65-36bf-1337-34b2d1f40bb4@kdbg.org","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"Jaydeep Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-10T16:29:32Z","receivedAt":"2022-03-10T16:29:40Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/9/22 00:02, Johannes Sixt wrote:\n> Am 08.03.22 um 17:54 schrieb jaydeepjd.8914@gmail.com:\n>> So, the final regexes are these, right?:\n> \n> Not quite.\n> \n>>\n>>       \"[a-zA-Z_][a-zA-Z0-9_]*\"\n>>       /* hexadecimal and binary numbers */\n>>       \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n>>       /* integers and floats */\n>>       \"|[0-9][.]?[0-9_]+([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> \n> This would not match 12.5 because you allow only a single digit before\n> the decimal point. Perhaps\n> \n> \t\"|[0-9][.0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> \n\nThe problem with this approach is that it matches `2..5` as a single token.\nHowever in Kotlin, `..` is used to specify a range so 2..5 should be broken into\n2 .. and 5.\n"},{"id":"451068","messageId":"7214a40b-c067-0465-28da-fb303591d876@kdbg.org","threadId":"57489","inReplyTo":"64677295-e7fd-ba4b-ce68-fe62132ca504@gmail.com","subject":"Re: [PATCH v5] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-10T19:11:11Z","receivedAt":"2022-03-10T19:11:15Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 10.03.22 um 17:29 schrieb Jaydeep Das:\n>>     \"|[0-9][.0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n>>\n> \n> The problem with this approach is that it matches `2..5` as a single token.\n> However in Kotlin, `..` is used to specify a range so 2..5 should be\n> broken into\n> 2 .. and 5.\n\nGood catch. Then we have to be more restrictive with the fractional part:\n\n\t\"|[0-9][0-9_]*([.][0-9_]*)([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\n-- Hannes\n"},{"id":"451112","messageId":"20220311072716.674808-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH v6] userdiff: add builtin diff driver for kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-11T07:27:16Z","receivedAt":"2022-03-11T07:27:48Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 ++++\n t/t4018/kotlin-enum-class       |  5 ++++\n t/t4018/kotlin-fun              |  5 ++++\n t/t4018/kotlin-inheritace-class |  5 ++++\n t/t4018/kotlin-inline-class     |  5 ++++\n t/t4018/kotlin-interface        |  5 ++++\n t/t4018/kotlin-nested-fun       |  9 +++++++\n t/t4018/kotlin-public-class     |  5 ++++\n t/t4018/kotlin-sealed-class     |  5 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 43 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 30 +++++++++++++++++++++++\n t/t4034/kotlin/pre              | 30 +++++++++++++++++++++++\n userdiff.c                      | 12 +++++++++\n 15 files changed, 167 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..74516cc453\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,43 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 11ea3de..2e1df4c 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,30 +1,30 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 1<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 2<RESET>00_000\n+a<RED>==<RESET><GREEN>===<RESET>b\n+a<RED>!!<RESET><GREEN>!=<RESET>b\n+<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n+X.<RED>fill<RESET><GREEN>find<RESET>()\n+X.<RED>u<RESET><GREEN>f<RESET>+1\n+X.u<RED>-<RESET><GREEN>+<RESET>2\n+a<RED>.<RESET><GREEN>..<RESET>b\n+a<RED>?.<RESET><GREEN>?:<RESET>b\n+<RED>.32_00_456<RESET><GREEN>.32_00_446<RESET>\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..2e1df4c6d5\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,30 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\n+a===b\n+a!=b\n+_33.find(arr)\n+X.find()\n+X.f+1\n+X.u+2\n+a..b\n+a?:b\n+.32_00_446\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..11ea3de665\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,30 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\n+a==b\n+a!!b\n+_32.find(arr)\n+X.fill()\n+X.u+1\n+X.u-2\n+a.b\n+a?.b\n+.32_00_456\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..c416c9b426 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,18 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[0-9][0-9_]*([.][0-9_]*)([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n+\t /* floating point numbers beginning with decimal point */\n+\t \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|[?:.][.:]\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"451161","messageId":"16543315-8515-a4d7-d75b-e7fe9731a7cf@kdbg.org","threadId":"57489","inReplyTo":"20220311072716.674808-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH v6] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-11T20:07:06Z","receivedAt":"2022-03-11T20:07:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 11.03.22 um 08:27 schrieb Jaydeep P Das:\n> The xfuncname pattern finds func/class declarations\n> in diffs to display as a hunk header. The word_regex\n> pattern finds individual tokens in Kotlin code to generate\n> appropriate diffs.\n> \n> This patch adds xfuncname regex and word_regex for Kotlin\n> language.\n> \n> Signed-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n> ---\n\nThank you. At first, I thought this round is it, but then I noticed this\nline:\n\n> +<RED>0xFF_EC_DE_5E 0b100_000 1<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 2<RESET>00_000\n\nNotice how the change from 100_000 to 200_000 breaks out the first digit\ninto its own token.\n\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..c416c9b426 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t /* hexadecimal and binary numbers */\n> +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> +\t /* integers and floats */\n> +\t \"|[0-9][0-9_]*([.][0-9_]*)([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n\nThis line matches a non-empty digit sequence of any length, and I\nthought the longest match would win. Why is that not the case here?\nFrankly, I'm scratching my head over it. Any ideas?\n\n> +\t /* floating point numbers beginning with decimal point */\n> +\t \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n> +\t /* unary and binary operators */\n> +\t \"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|[?:.][.:]\"),\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n-- Hannes\n"},{"id":"451208","messageId":"62e13889-315a-1a42-f37b-390702c0aa9d@gmail.com","threadId":"57489","inReplyTo":"16543315-8515-a4d7-d75b-e7fe9731a7cf@kdbg.org","subject":"Re: [PATCH v6] userdiff: add builtin diff driver for kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-12T04:36:08Z","receivedAt":"2022-03-12T04:36:20Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/12/22 1:37 AM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 11.03.22 um 08:27 schrieb Jaydeep P Das:\n> > The xfuncname pattern finds func/class declarations\n> > in diffs to display as a hunk header. The word_regex\n> > pattern finds individual tokens in Kotlin code to generate\n> > appropriate diffs.\n> >\n> > This patch adds xfuncname regex and word_regex for Kotlin\n> > language.\n> >\n> > Signed-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n> > ---\n> \n> Thank you. At first, I thought this round is it, but then I noticed this\n> line:\n> \n> > +<RED>0xFF_EC_DE_5E 0b100_000 1<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 2<RESET>00_000\n> \n> Notice how the change from 100_000 to 200_000 breaks out the first digit\n> into its own token.\n\nWow. I completely missed it.\n\n> > diff --git a/userdiff.c b/userdiff.c\n> > index 8578cb0d12..c416c9b426 100644\n> > --- a/userdiff.c\n> > +++ b/userdiff.c\n> > @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n> >   \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n> >   \t \"|[-+*/<>%&^|=!]=\"\n> >   \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> > +PATTERNS(\"kotlin\",\n> > +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> > +\t /* -- */\n> > +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> > +\t /* hexadecimal and binary numbers */\n> > +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> > +\t /* integers and floats */\n> > +\t \"|[0-9][0-9_]*([.][0-9_]*)([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> \n> This line matches a non-empty digit sequence of any length, and I\n> thought the longest match would win. Why is that not the case here?\n> Frankly, I'm scratching my head over it. Any ideas?\n\nYes. The capture group ([.][0-9_]*) should occur once or zero times. So\nthis `([.][0-9_]*)?` will fix it.\n\n\n"},{"id":"451209","messageId":"20220312044832.718356-1-jaydeepjd.8914@gmail.com","threadId":"57489","inReplyTo":"20220301070226.2477769-1-jaydeepjd.8914@gmail.com","subject":"[PATCH v7] userdiff: add builtin diff driver for kotlin language.","fromName":"Jaydeep P Das","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-12T04:48:32Z","receivedAt":"2022-03-12T04:49:06Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"The xfuncname pattern finds func/class declarations\nin diffs to display as a hunk header. The word_regex\npattern finds individual tokens in Kotlin code to generate\nappropriate diffs.\n\nThis patch adds xfuncname regex and word_regex for Kotlin\nlanguage.\n\nSigned-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018/kotlin-class            |  5 ++++\n t/t4018/kotlin-enum-class       |  5 ++++\n t/t4018/kotlin-fun              |  5 ++++\n t/t4018/kotlin-inheritace-class |  5 ++++\n t/t4018/kotlin-inline-class     |  5 ++++\n t/t4018/kotlin-interface        |  5 ++++\n t/t4018/kotlin-nested-fun       |  9 +++++++\n t/t4018/kotlin-public-class     |  5 ++++\n t/t4018/kotlin-sealed-class     |  5 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/kotlin/expect           | 43 +++++++++++++++++++++++++++++++++\n t/t4034/kotlin/post             | 30 +++++++++++++++++++++++\n t/t4034/kotlin/pre              | 30 +++++++++++++++++++++++\n userdiff.c                      | 12 +++++++++\n 15 files changed, 167 insertions(+)\n create mode 100644 t/t4018/kotlin-class\n create mode 100644 t/t4018/kotlin-enum-class\n create mode 100644 t/t4018/kotlin-fun\n create mode 100644 t/t4018/kotlin-inheritace-class\n create mode 100644 t/t4018/kotlin-inline-class\n create mode 100644 t/t4018/kotlin-interface\n create mode 100644 t/t4018/kotlin-nested-fun\n create mode 100644 t/t4018/kotlin-public-class\n create mode 100644 t/t4018/kotlin-sealed-class\n create mode 100644 t/t4034/kotlin/expect\n create mode 100644 t/t4034/kotlin/post\n create mode 100644 t/t4034/kotlin/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex a71dad2674..4b36d51beb 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -829,6 +829,8 @@ patterns are available:\n \n - `java` suitable for source code in the Java language.\n \n+- `kotlin` suitable for source code in the Kotlin language.\n+\n - `markdown` suitable for Markdown documents.\n \n - `matlab` suitable for source code in the MATLAB and Octave languages.\ndiff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\nnew file mode 100644\nindex 0000000000..bb864f22e6\n--- /dev/null\n+++ b/t/t4018/kotlin-class\n@@ -0,0 +1,5 @@\n+class RIGHT {\n+\t//comment\n+\t//comment\n+\treturn ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\nnew file mode 100644\nindex 0000000000..8885f908fd\n--- /dev/null\n+++ b/t/t4018/kotlin-enum-class\n@@ -0,0 +1,5 @@\n+enum class RIGHT{\n+\t// Left\n+\t// a comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\nnew file mode 100644\nindex 0000000000..2a60280256\n--- /dev/null\n+++ b/t/t4018/kotlin-fun\n@@ -0,0 +1,5 @@\n+fun RIGHT(){\n+\t//a comment\n+\t//b comment\n+    return ChangeMe()\n+}\ndiff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\nnew file mode 100644\nindex 0000000000..77376c1f05\n--- /dev/null\n+++ b/t/t4018/kotlin-inheritace-class\n@@ -0,0 +1,5 @@\n+open class RIGHT{\n+\t// a comment\n+\t// b comment\n+\t// ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\nnew file mode 100644\nindex 0000000000..7bf46dd8d4\n--- /dev/null\n+++ b/t/t4018/kotlin-inline-class\n@@ -0,0 +1,5 @@\n+value class RIGHT(Args){\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\nnew file mode 100644\nindex 0000000000..f686ba7770\n--- /dev/null\n+++ b/t/t4018/kotlin-interface\n@@ -0,0 +1,5 @@\n+interface RIGHT{\n+\t//another comment\n+\t//another comment\n+\t//ChangeMe\n+}\ndiff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\nnew file mode 100644\nindex 0000000000..12186858cb\n--- /dev/null\n+++ b/t/t4018/kotlin-nested-fun\n@@ -0,0 +1,9 @@\n+class LEFT{\n+\tclass CENTER{\n+\t\tfun RIGHT(  a:Int){\n+\t\t\t//comment\n+\t\t\t//comment\n+\t\t\tChangeMe\n+\t\t}\n+\t}\n+}\ndiff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\nnew file mode 100644\nindex 0000000000..9433fcc226\n--- /dev/null\n+++ b/t/t4018/kotlin-public-class\n@@ -0,0 +1,5 @@\n+public class RIGHT{\n+\t//comment1\n+\t//comment2\n+\tChangeMe\n+}\ndiff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\nnew file mode 100644\nindex 0000000000..0efa4a4eaf\n--- /dev/null\n+++ b/t/t4018/kotlin-sealed-class\n@@ -0,0 +1,5 @@\n+sealed class RIGHT {\n+\t// a comment\n+\t// b comment\n+\tChangeMe\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex d5abcf4b4c..15764ee9ac 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -324,6 +324,7 @@ test_language_driver dts\n test_language_driver fortran\n test_language_driver html\n test_language_driver java\n+test_language_driver kotlin\n test_language_driver matlab\n test_language_driver objc\n test_language_driver pascal\ndiff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\nnew file mode 100644\nindex 0000000000..7f76f7540d\n--- /dev/null\n+++ b/t/t4034/kotlin/expect\n@@ -0,0 +1,43 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 11ea3de..2e1df4c 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,30 +1,30 @@<RESET>\n+println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n+<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n+[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n+!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n+a <RED>shr<RESET><GREEN>shl<RESET> b\n+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> and <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>^<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET> or <RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n+a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n+a<RED><<=<RESET><GREEN><=<RESET>b\n+a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n+<RED>a<RESET><GREEN>x<RESET>,y\n+--a<RED>==<RESET><GREEN>!=<RESET>--b\n+a++<RED>==<RESET><GREEN>!=<RESET>++b\n+<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n+a<RED>==<RESET><GREEN>===<RESET>b\n+a<RED>!!<RESET><GREEN>!=<RESET>b\n+<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n+X.<RED>fill<RESET><GREEN>find<RESET>()\n+X.<RED>u<RESET><GREEN>f<RESET>+1\n+X.u<RED>-<RESET><GREEN>+<RESET>2\n+a<RED>.<RESET><GREEN>..<RESET>b\n+a<RED>?.<RESET><GREEN>?:<RESET>b\n+<RED>.32_00_456<RESET><GREEN>.32_00_446<RESET>\ndiff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\nnew file mode 100644\nindex 0000000000..2e1df4c6d5\n--- /dev/null\n+++ b/t/t4034/kotlin/post\n@@ -0,0 +1,30 @@\n+println(\"Hello World?\")\n+(1) (-1e10) (0xabcdef) 'y'\n+[x] x->y x.y\n+!x x.inv() x*y x&y\n+x*y x/y x%y\n+x+y x-y\n+a shl b\n+x<y x<=y x>y x>=y\n+x==y x!=y x===y\n+x and y\n+x^y\n+x or y\n+x&&y x||y\n+x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n+a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n+a<=b\n+a|b a&b\n+x,y\n+--a!=--b\n+a++!=++b\n+0xFF_E1_DE_5E 0b100_100 200_000\n+a===b\n+a!=b\n+_33.find(arr)\n+X.find()\n+X.f+1\n+X.u+2\n+a..b\n+a?:b\n+.32_00_446\ndiff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\nnew file mode 100644\nindex 0000000000..11ea3de665\n--- /dev/null\n+++ b/t/t4034/kotlin/pre\n@@ -0,0 +1,30 @@\n+println(\"Hello World!\\n\")\n+1 -1e10 0xabcdef 'x'\n+[a] a->b a.b\n+!a a.inv() a*b a&b\n+a*b a/b a%b\n+a+b a-b\n+a shr b\n+a<b a<=b a>b a>=b\n+a==b a!=b a===b\n+a and b\n+a^b\n+a or b\n+a&&b a||b\n+a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n+a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n+a<<=b\n+a||b a&&b\n+a,y\n+--a==--b\n+a++==++b\n+0xFF_EC_DE_5E 0b100_000 100_000\n+a==b\n+a!!b\n+_32.find(arr)\n+X.fill()\n+X.u+1\n+X.u-2\n+a.b\n+a?.b\n+.32_00_456\ndiff --git a/userdiff.c b/userdiff.c\nindex 8578cb0d12..0f6c14659b 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -168,6 +168,18 @@ PATTERNS(\"java\",\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=\"\n \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n+PATTERNS(\"kotlin\",\n+\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n+\t /* -- */\n+\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n+\t /* hexadecimal and binary numbers */\n+\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n+\t /* integers and floats */\n+\t \"|[0-9][0-9_]*([.][0-9_]*)?([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n+\t /* floating point numbers beginning with decimal point */\n+\t \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n+\t /* unary and binary operators */\n+\t \"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|[?:.][.:]\"),\n PATTERNS(\"markdown\",\n \t \"^ {0,3}#{1,6}[ \\t].*\",\n \t /* -- */\n-- \n2.35.1\n\n"},{"id":"451213","messageId":"90d0b9b5-65d8-4d16-10b0-f10ae5e72942@kdbg.org","threadId":"57489","inReplyTo":"62e13889-315a-1a42-f37b-390702c0aa9d@gmail.com","subject":"Re: [PATCH v6] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-12T08:36:56Z","receivedAt":"2022-03-12T08:37:05Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 12.03.22 um 05:36 schrieb jaydeepjd.8914@gmail.com:\n> On 3/12/22 1:37 AM, Johannes Sixt <j6t@kdbg.org> wrote:\n>> Am 11.03.22 um 08:27 schrieb Jaydeep P Das:\n>> > diff --git a/userdiff.c b/userdiff.c\n>> > index 8578cb0d12..c416c9b426 100644\n>> > --- a/userdiff.c\n>> > +++ b/userdiff.c\n>> > @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n>> >        \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>> >        \"|[-+*/<>%&^|=!]=\"\n>> >        \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n>> > +PATTERNS(\"kotlin\",\n>> > +     \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n>> > +     /* -- */\n>> > +     \"[a-zA-Z_][a-zA-Z0-9_]*\"\n>> > +     /* hexadecimal and binary numbers */\n>> > +     \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n>> > +     /* integers and floats */\n>> > +     \"|[0-9][0-9_]*([.][0-9_]*)([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n>>\n>> This line matches a non-empty digit sequence of any length, and I\n>> thought the longest match would win. Why is that not the case here?\n>> Frankly, I'm scratching my head over it. Any ideas?\n> \n> Yes. The capture group ([.][0-9_]*) should occur once or zero times. So\n> this `([.][0-9_]*)?` will fix it.\n\nOh, good catch! That's the missing piece.\n\n-- Hannes\n"},{"id":"451214","messageId":"1f10cfa1-83b8-49b1-f4df-829cada788bd@kdbg.org","threadId":"57489","inReplyTo":"20220312044832.718356-1-jaydeepjd.8914@gmail.com","subject":"Re: [PATCH v7] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-12T08:59:05Z","receivedAt":"2022-03-12T08:59:16Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 12.03.22 um 05:48 schrieb Jaydeep P Das:\n> The xfuncname pattern finds func/class declarations\n> in diffs to display as a hunk header. The word_regex\n> pattern finds individual tokens in Kotlin code to generate\n> appropriate diffs.\n> \n> This patch adds xfuncname regex and word_regex for Kotlin\n> language.\n> \n> Signed-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n\nThis round looks good. Thank you for your perseverance.\n\nAcked-by: Johannes Sixt <j6t@kdbg.org>\n\n> ---\n>  Documentation/gitattributes.txt |  2 ++\n>  t/t4018/kotlin-class            |  5 ++++\n>  t/t4018/kotlin-enum-class       |  5 ++++\n>  t/t4018/kotlin-fun              |  5 ++++\n>  t/t4018/kotlin-inheritace-class |  5 ++++\n>  t/t4018/kotlin-inline-class     |  5 ++++\n>  t/t4018/kotlin-interface        |  5 ++++\n>  t/t4018/kotlin-nested-fun       |  9 +++++++\n>  t/t4018/kotlin-public-class     |  5 ++++\n>  t/t4018/kotlin-sealed-class     |  5 ++++\n>  t/t4034-diff-words.sh           |  1 +\n>  t/t4034/kotlin/expect           | 43 +++++++++++++++++++++++++++++++++\n>  t/t4034/kotlin/post             | 30 +++++++++++++++++++++++\n>  t/t4034/kotlin/pre              | 30 +++++++++++++++++++++++\n>  userdiff.c                      | 12 +++++++++\n>  15 files changed, 167 insertions(+)\n>  create mode 100644 t/t4018/kotlin-class\n>  create mode 100644 t/t4018/kotlin-enum-class\n>  create mode 100644 t/t4018/kotlin-fun\n>  create mode 100644 t/t4018/kotlin-inheritace-class\n>  create mode 100644 t/t4018/kotlin-inline-class\n>  create mode 100644 t/t4018/kotlin-interface\n>  create mode 100644 t/t4018/kotlin-nested-fun\n>  create mode 100644 t/t4018/kotlin-public-class\n>  create mode 100644 t/t4018/kotlin-sealed-class\n>  create mode 100644 t/t4034/kotlin/expect\n>  create mode 100644 t/t4034/kotlin/post\n>  create mode 100644 t/t4034/kotlin/pre\n> \n> diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\n> index a71dad2674..4b36d51beb 100644\n> --- a/Documentation/gitattributes.txt\n> +++ b/Documentation/gitattributes.txt\n> @@ -829,6 +829,8 @@ patterns are available:\n>  \n>  - `java` suitable for source code in the Java language.\n>  \n> +- `kotlin` suitable for source code in the Kotlin language.\n> +\n>  - `markdown` suitable for Markdown documents.\n>  \n>  - `matlab` suitable for source code in the MATLAB and Octave languages.\n> diff --git a/t/t4018/kotlin-class b/t/t4018/kotlin-class\n> new file mode 100644\n> index 0000000000..bb864f22e6\n> --- /dev/null\n> +++ b/t/t4018/kotlin-class\n> @@ -0,0 +1,5 @@\n> +class RIGHT {\n> +\t//comment\n> +\t//comment\n> +\treturn ChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-enum-class b/t/t4018/kotlin-enum-class\n> new file mode 100644\n> index 0000000000..8885f908fd\n> --- /dev/null\n> +++ b/t/t4018/kotlin-enum-class\n> @@ -0,0 +1,5 @@\n> +enum class RIGHT{\n> +\t// Left\n> +\t// a comment\n> +\tChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-fun b/t/t4018/kotlin-fun\n> new file mode 100644\n> index 0000000000..2a60280256\n> --- /dev/null\n> +++ b/t/t4018/kotlin-fun\n> @@ -0,0 +1,5 @@\n> +fun RIGHT(){\n> +\t//a comment\n> +\t//b comment\n> +    return ChangeMe()\n> +}\n> diff --git a/t/t4018/kotlin-inheritace-class b/t/t4018/kotlin-inheritace-class\n> new file mode 100644\n> index 0000000000..77376c1f05\n> --- /dev/null\n> +++ b/t/t4018/kotlin-inheritace-class\n> @@ -0,0 +1,5 @@\n> +open class RIGHT{\n> +\t// a comment\n> +\t// b comment\n> +\t// ChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-inline-class b/t/t4018/kotlin-inline-class\n> new file mode 100644\n> index 0000000000..7bf46dd8d4\n> --- /dev/null\n> +++ b/t/t4018/kotlin-inline-class\n> @@ -0,0 +1,5 @@\n> +value class RIGHT(Args){\n> +\t// a comment\n> +\t// b comment\n> +\tChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-interface b/t/t4018/kotlin-interface\n> new file mode 100644\n> index 0000000000..f686ba7770\n> --- /dev/null\n> +++ b/t/t4018/kotlin-interface\n> @@ -0,0 +1,5 @@\n> +interface RIGHT{\n> +\t//another comment\n> +\t//another comment\n> +\t//ChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-nested-fun b/t/t4018/kotlin-nested-fun\n> new file mode 100644\n> index 0000000000..12186858cb\n> --- /dev/null\n> +++ b/t/t4018/kotlin-nested-fun\n> @@ -0,0 +1,9 @@\n> +class LEFT{\n> +\tclass CENTER{\n> +\t\tfun RIGHT(  a:Int){\n> +\t\t\t//comment\n> +\t\t\t//comment\n> +\t\t\tChangeMe\n> +\t\t}\n> +\t}\n> +}\n> diff --git a/t/t4018/kotlin-public-class b/t/t4018/kotlin-public-class\n> new file mode 100644\n> index 0000000000..9433fcc226\n> --- /dev/null\n> +++ b/t/t4018/kotlin-public-class\n> @@ -0,0 +1,5 @@\n> +public class RIGHT{\n> +\t//comment1\n> +\t//comment2\n> +\tChangeMe\n> +}\n> diff --git a/t/t4018/kotlin-sealed-class b/t/t4018/kotlin-sealed-class\n> new file mode 100644\n> index 0000000000..0efa4a4eaf\n> --- /dev/null\n> +++ b/t/t4018/kotlin-sealed-class\n> @@ -0,0 +1,5 @@\n> +sealed class RIGHT {\n> +\t// a comment\n> +\t// b comment\n> +\tChangeMe\n> +}\n> diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\n> index d5abcf4b4c..15764ee9ac 100755\n> --- a/t/t4034-diff-words.sh\n> +++ b/t/t4034-diff-words.sh\n> @@ -324,6 +324,7 @@ test_language_driver dts\n>  test_language_driver fortran\n>  test_language_driver html\n>  test_language_driver java\n> +test_language_driver kotlin\n>  test_language_driver matlab\n>  test_language_driver objc\n>  test_language_driver pascal\n> diff --git a/t/t4034/kotlin/expect b/t/t4034/kotlin/expect\n> new file mode 100644\n> index 0000000000..7f76f7540d\n> --- /dev/null\n> +++ b/t/t4034/kotlin/expect\n> @@ -0,0 +1,43 @@\n> +<BOLD>diff --git a/pre b/post<RESET>\n> +<BOLD>index 11ea3de..2e1df4c 100644<RESET>\n> +<BOLD>--- a/pre<RESET>\n> +<BOLD>+++ b/post<RESET>\n> +<CYAN>@@ -1,30 +1,30 @@<RESET>\n> +println(\"Hello World<RED>!\\n<RESET><GREEN>?<RESET>\")\n> +<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>'\n> +[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET>\n> +!<RED>a a<RESET><GREEN>x x<RESET>.inv() <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>\n> +a <RED>shr<RESET><GREEN>shl<RESET> b\n> +<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b a<RESET><GREEN>y x<RESET>===<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> and <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>^<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET> or <RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET>\n> +<RED>a<RESET><GREEN>y<RESET>\n> +<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET><GREEN>y<RESET>\n> +a<RED>=<RESET><GREEN>+=<RESET>b c<RED>+=<RESET><GREEN>=<RESET>d e<RED>-=<RESET><GREEN><=<RESET>f g<RED>*=<RESET><GREEN>>=<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v\n> +a<RED><<=<RESET><GREEN><=<RESET>b\n> +a<RED>||<RESET><GREEN>|<RESET>b a<RED>&&<RESET><GREEN>&<RESET>b\n> +<RED>a<RESET><GREEN>x<RESET>,y\n> +--a<RED>==<RESET><GREEN>!=<RESET>--b\n> +a++<RED>==<RESET><GREEN>!=<RESET>++b\n> +<RED>0xFF_EC_DE_5E 0b100_000 100_000<RESET><GREEN>0xFF_E1_DE_5E 0b100_100 200_000<RESET>\n> +a<RED>==<RESET><GREEN>===<RESET>b\n> +a<RED>!!<RESET><GREEN>!=<RESET>b\n> +<RED>_32<RESET><GREEN>_33<RESET>.find(arr)\n> +X.<RED>fill<RESET><GREEN>find<RESET>()\n> +X.<RED>u<RESET><GREEN>f<RESET>+1\n> +X.u<RED>-<RESET><GREEN>+<RESET>2\n> +a<RED>.<RESET><GREEN>..<RESET>b\n> +a<RED>?.<RESET><GREEN>?:<RESET>b\n> +<RED>.32_00_456<RESET><GREEN>.32_00_446<RESET>\n> diff --git a/t/t4034/kotlin/post b/t/t4034/kotlin/post\n> new file mode 100644\n> index 0000000000..2e1df4c6d5\n> --- /dev/null\n> +++ b/t/t4034/kotlin/post\n> @@ -0,0 +1,30 @@\n> +println(\"Hello World?\")\n> +(1) (-1e10) (0xabcdef) 'y'\n> +[x] x->y x.y\n> +!x x.inv() x*y x&y\n> +x*y x/y x%y\n> +x+y x-y\n> +a shl b\n> +x<y x<=y x>y x>=y\n> +x==y x!=y x===y\n> +x and y\n> +x^y\n> +x or y\n> +x&&y x||y\n> +x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y\n> +a+=b c=d e<=f g>=h i/j k%l m<<n o>>p q&r s^t u|v\n> +a<=b\n> +a|b a&b\n> +x,y\n> +--a!=--b\n> +a++!=++b\n> +0xFF_E1_DE_5E 0b100_100 200_000\n> +a===b\n> +a!=b\n> +_33.find(arr)\n> +X.find()\n> +X.f+1\n> +X.u+2\n> +a..b\n> +a?:b\n> +.32_00_446\n> diff --git a/t/t4034/kotlin/pre b/t/t4034/kotlin/pre\n> new file mode 100644\n> index 0000000000..11ea3de665\n> --- /dev/null\n> +++ b/t/t4034/kotlin/pre\n> @@ -0,0 +1,30 @@\n> +println(\"Hello World!\\n\")\n> +1 -1e10 0xabcdef 'x'\n> +[a] a->b a.b\n> +!a a.inv() a*b a&b\n> +a*b a/b a%b\n> +a+b a-b\n> +a shr b\n> +a<b a<=b a>b a>=b\n> +a==b a!=b a===b\n> +a and b\n> +a^b\n> +a or b\n> +a&&b a||b\n> +a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b\n> +a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v\n> +a<<=b\n> +a||b a&&b\n> +a,y\n> +--a==--b\n> +a++==++b\n> +0xFF_EC_DE_5E 0b100_000 100_000\n> +a==b\n> +a!!b\n> +_32.find(arr)\n> +X.fill()\n> +X.u+1\n> +X.u-2\n> +a.b\n> +a?.b\n> +.32_00_456\n> diff --git a/userdiff.c b/userdiff.c\n> index 8578cb0d12..0f6c14659b 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -168,6 +168,18 @@ PATTERNS(\"java\",\n>  \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n>  \t \"|[-+*/<>%&^|=!]=\"\n>  \t \"|--|\\\\+\\\\+|<<=?|>>>?=?|&&|\\\\|\\\\|\"),\n> +PATTERNS(\"kotlin\",\n> +\t \"^[ \\t]*(([a-z]+[ \\t]+)*(fun|class|interface)[ \\t]+.*)$\",\n> +\t /* -- */\n> +\t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n> +\t /* hexadecimal and binary numbers */\n> +\t \"|0[xXbB][0-9a-fA-F_]+[lLuU]*\"\n> +\t /* integers and floats */\n> +\t \"|[0-9][0-9_]*([.][0-9_]*)?([Ee][-+]?[0-9]+)?[fFlLuU]*\"\n> +\t /* floating point numbers beginning with decimal point */\n> +\t \"|[.][0-9][0-9_]*([Ee][-+]?[0-9]+)?[fFlLuU]?\"\n> +\t /* unary and binary operators */\n> +\t \"|[-+*/<>%&^|=!]==?|--|\\\\+\\\\+|<<=|>>=|&&|\\\\|\\\\||->|\\\\.\\\\*|!!|[?:.][.:]\"),\n>  PATTERNS(\"markdown\",\n>  \t \"^ {0,3}#{1,6}[ \\t].*\",\n>  \t /* -- */\n\n"},{"id":"451250","messageId":"634b6049-7b06-876d-499f-7aa5880a47f4@gmail.com","threadId":"57489","inReplyTo":"1f10cfa1-83b8-49b1-f4df-829cada788bd@kdbg.org","subject":"Re: [PATCH v7] userdiff: add builtin diff driver for kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-13T17:02:36Z","receivedAt":"2022-03-13T17:02:44Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"\n\nOn 3/12/22 2:29 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 12.03.22 um 05:48 schrieb Jaydeep P Das:\n> > The xfuncname pattern finds func/class declarations\n> > in diffs to display as a hunk header. The word_regex\n> > pattern finds individual tokens in Kotlin code to generate\n> > appropriate diffs.\n> >\n> > This patch adds xfuncname regex and word_regex for Kotlin\n> > language.\n> >\n> > Signed-off-by: Jaydeep P Das <jaydeepjd.8914@gmail.com>\n> \n> This round looks good. Thank you for your perseverance.\n> \n> Acked-by: Johannes Sixt <j6t@kdbg.org>\n\n\nThanks. Should I CC Junio or will it be here for some more reviews?\n"},{"id":"451251","messageId":"d7516e3e-b30a-ea77-3d84-131d704b9ed8@gmail.com","threadId":"57489","inReplyTo":"634b6049-7b06-876d-499f-7aa5880a47f4@gmail.com","subject":"Re: [PATCH v7] userdiff: add builtin diff driver for kotlin language.","fromName":"","fromEmail":"jaydeepjd.8914@gmail.com","sentAt":"2022-03-13T17:09:01Z","receivedAt":"2022-03-13T17:09:11Z","isPatch":true,"sender":{"key":"jaydeepjd.8914@gmail.com","avatar":"https://avatars.githubusercontent.com/u/64089730?v=4"},"body":"Also, since according to GSoC timeline, the current period is to\ndiscuss application ideas with mentoring organizations, what should I\ndo next? \n\nI have seen the GSoC application ideas and integrating\nthe remaining git commands to work with sparse-index looks interesting.\nMaybe I could start off with that?\n\nThanks,\nJaydeep.\n"},{"id":"451269","messageId":"4b8d0d1b-79b8-1a25-748f-ad7e202d93ea@kdbg.org","threadId":"57489","inReplyTo":"634b6049-7b06-876d-499f-7aa5880a47f4@gmail.com","subject":"Re: [PATCH v7] userdiff: add builtin diff driver for kotlin language.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2022-03-13T21:36:20Z","receivedAt":"2022-03-13T21:36:30Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 13.03.22 um 18:02 schrieb jaydeepjd.8914@gmail.com:\n> Thanks. Should I CC Junio or will it be here for some more reviews?\n\nIn my previous reply I Cc'ed Junio to notify him that we have reached a\nconclusion. Usually, he'll pick up the patch after that. If you do not\nsee the topic mentioned in the next \"What's cooking\" report or it refers\nto an outdated version, that would be an appropriate time for a reminder.\n\n-- Hannes\n"}]}