diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e285b0cbcc16..b650aacb84b4 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -16,5 +16,4 @@ RUN mkdir -p "$HOME/.gradle" && \ echo "org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" > "$HOME/.gradle/gradle.properties" && \ echo "org.gradle.caching=true" >> "$HOME/.gradle/gradle.properties" && \ echo "org.gradle.parallel=true" >> "$HOME/.gradle/gradle.properties" && \ - echo "org.gradle.configureondemand=true" >> "$HOME/.gradle/gradle.properties" && \ - echo "kapt.incremental.apt=true" >> "$HOME/.gradle/gradle.properties" \ No newline at end of file + echo "org.gradle.configureondemand=true" >> "$HOME/.gradle/gradle.properties" diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index b5173d17a41f..62d6a954633d 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -74,6 +74,5 @@ jobs: echo "org.gradle.jvmargs=-Xmx5g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" echo "org.gradle.configureondemand=true" echo "org.gradle.configuration-cache=false" - echo "kapt.incremental.apt=true" } > "$HOME/.gradle/gradle.properties" scripts/analysis/analysis-wrapper.sh "${{ steps.get-vars.outputs.branch }}" "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" "$GITHUB_RUN_NUMBER" "${{ steps.get-vars.outputs.pr }}" diff --git a/.github/workflows/assembleFlavors.yml b/.github/workflows/assembleFlavors.yml index 5f30559fa8c3..b441af9045b9 100644 --- a/.github/workflows/assembleFlavors.yml +++ b/.github/workflows/assembleFlavors.yml @@ -35,5 +35,4 @@ jobs: echo "org.gradle.caching=true" >> gradle.properties echo "org.gradle.parallel=true" >> gradle.properties echo "org.gradle.configureondemand=true" >> gradle.properties - echo "kapt.incremental.apt=true" >> gradle.properties ./gradlew assemble${{ matrix.flavor }} diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 5a0f7839d234..5eeee4b8fddf 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -47,7 +47,7 @@ jobs: run: | mkdir -p "$HOME/.gradle" echo "org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" > "$HOME/.gradle/gradle.properties" - echo "org.gradle.caching=true; org.gradle.parallel=true; org.gradle.configureondemand=true; kapt.incremental.apt=true" >> "$HOME/.gradle/gradle.properties" + echo "org.gradle.caching=true; org.gradle.parallel=true; org.gradle.configureondemand=true" >> "$HOME/.gradle/gradle.properties" sed -i "/qa/,/\}/ s/versionCode.*/versionCode = ${{ github.event.number }}/" app/build.gradle.kts sed -i "/qa/,/\}/ s/versionName.*/versionName = \"${{ github.event.number }}\"/" app/build.gradle.kts ./gradlew assembleQaDebug diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index 2df2c792c9b3..c56f026d8bfc 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -73,7 +73,6 @@ jobs: echo "org.gradle.caching=true" >> $HOME/.gradle/gradle.properties echo "org.gradle.parallel=true" >> $HOME/.gradle/gradle.properties echo "org.gradle.configureondemand=true" >> $HOME/.gradle/gradle.properties - echo "kapt.incremental.apt=true" >> $HOME/.gradle/gradle.properties - name: Build gplay run: ./gradlew assembleGenericDebug diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7c5764b7af6b..6f19170814a0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,7 +24,6 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.compose) alias(libs.plugins.spotless) - alias(libs.plugins.kapt) alias(libs.plugins.ksp) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.parcelize) @@ -243,8 +242,6 @@ android { } -kapt.useBuildCache = true - ksp.arg("room.schemaLocation", "$projectDir/schemas") kotlin.compilerOptions.jvmTarget.set(JvmTarget.JVM_17) @@ -460,7 +457,6 @@ dependencies { // region Markdown rendering implementation(libs.bundles.markdown.rendering) - kapt(libs.prism4j.bundler) // endregion // region Image cropping / rotation diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt index 99b0bffc4bf3..c27010e98024 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt @@ -55,6 +55,7 @@ import io.noties.markwon.syntax.Prism4jThemeDefault import io.noties.markwon.syntax.SyntaxHighlightPlugin import io.noties.prism4j.Prism4j import io.noties.prism4j.annotations.PrismBundle +import third_parties.io.noties.prism4j.languages.MarkwonGrammarLocator import javax.inject.Inject @PrismBundle( diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/MarkwonGrammarLocator.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/MarkwonGrammarLocator.java new file mode 100644 index 000000000000..38774081983f --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/MarkwonGrammarLocator.java @@ -0,0 +1,209 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.noties.prism4j.GrammarLocator; +import io.noties.prism4j.Prism4j; + +public class MarkwonGrammarLocator implements GrammarLocator { + + @SuppressWarnings("ConstantConditions") + private static final Prism4j.Grammar NULL = + new Prism4j.Grammar() { + @NotNull + @Override + public String name() { + return null; + } + + @NotNull + @Override + public List tokens() { + return null; + } + }; + + private final Map cache = new HashMap<>(3); + + @Nullable + @Override + public Prism4j.Grammar grammar(@NotNull Prism4j prism4j, @NotNull String language) { + + final String name = realLanguageName(language); + + Prism4j.Grammar grammar = cache.get(name); + if (grammar != null) { + if (NULL == grammar) { + grammar = null; + } + return grammar; + } + + grammar = obtainGrammar(prism4j, name); + if (grammar == null) { + cache.put(name, NULL); + } else { + cache.put(name, grammar); + triggerModify(prism4j, name); + } + + return grammar; + } + + @NotNull + protected String realLanguageName(@NotNull String name) { + final String out; + switch (name) { + case "dotnet": + out = "csharp"; + break; + case "js": + out = "javascript"; + break; + case "jsonp": + out = "json"; + break; + case "xml": + case "html": + case "mathml": + case "svg": + out = "markup"; + break; + default: + out = name; + } + return out; + } + + @Nullable + protected Prism4j.Grammar obtainGrammar(@NotNull Prism4j prism4j, @NotNull String name) { + final Prism4j.Grammar grammar; + switch (name) { + case "c": + grammar = Prism_c.create(prism4j); + break; + case "clike": + grammar = Prism_clike.create(prism4j); + break; + case "clojure": + grammar = Prism_clojure.create(prism4j); + break; + case "cpp": + grammar = Prism_cpp.create(prism4j); + break; + case "csharp": + grammar = Prism_csharp.create(prism4j); + break; + case "css": + grammar = Prism_css.create(prism4j); + break; + case "dart": + grammar = Prism_dart.create(prism4j); + break; + case "git": + grammar = Prism_git.create(prism4j); + break; + case "go": + grammar = Prism_go.create(prism4j); + break; + case "groovy": + grammar = Prism_groovy.create(prism4j); + break; + case "java": + grammar = Prism_java.create(prism4j); + break; + case "javascript": + grammar = Prism_javascript.create(prism4j); + break; + case "json": + grammar = Prism_json.create(prism4j); + break; + case "kotlin": + grammar = Prism_kotlin.create(prism4j); + break; + case "latex": + grammar = Prism_latex.create(prism4j); + break; + case "makefile": + grammar = Prism_makefile.create(prism4j); + break; + case "markdown": + grammar = Prism_markdown.create(prism4j); + break; + case "markup": + grammar = Prism_markup.create(prism4j); + break; + case "python": + grammar = Prism_python.create(prism4j); + break; + case "scala": + grammar = Prism_scala.create(prism4j); + break; + case "sql": + grammar = Prism_sql.create(prism4j); + break; + case "swift": + grammar = Prism_swift.create(prism4j); + break; + case "yaml": + grammar = Prism_yaml.create(prism4j); + break; + default: + grammar = null; + } + return grammar; + } + + protected void triggerModify(@NotNull Prism4j prism4j, @NotNull String name) { + switch (name) { + case "markup": + prism4j.grammar("css"); + prism4j.grammar("javascript"); + break; + } + } + + @Override + @NotNull + public Set languages() { + final Set set = new HashSet(23); + set.add("c"); + set.add("clike"); + set.add("clojure"); + set.add("cpp"); + set.add("csharp"); + set.add("css"); + set.add("dart"); + set.add("git"); + set.add("go"); + set.add("groovy"); + set.add("java"); + set.add("javascript"); + set.add("json"); + set.add("kotlin"); + set.add("latex"); + set.add("makefile"); + set.add("markdown"); + set.add("markup"); + set.add("python"); + set.add("scala"); + set.add("sql"); + set.add("swift"); + set.add("yaml"); + return set; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_c.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_c.java new file mode 100644 index 000000000000..fc4493250820 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_c.java @@ -0,0 +1,66 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_c { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar c = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "c", + new GrammarUtils.TokenFilter() { + @Override + public boolean test(@NotNull Prism4j.Token token) { + final String name = token.name(); + return !"class-name".equals(name) && !"boolean".equals(name); + } + }, + token("keyword", pattern(compile("\\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\\b"))), + token("operator", pattern(compile("-[>-]?|\\+\\+?|!=?|<>?=?|==?|&&?|\\|\\|?|[~^%?*\\/]"))), + token("number", pattern(compile("(?:\\b0x[\\da-f]+|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:e[+-]?\\d+)?)[ful]*", CASE_INSENSITIVE))) + ); + + GrammarUtils.insertBeforeToken(c, "string", + token("macro", pattern( + compile("(^\\s*)#\\s*[a-z]+(?:[^\\r\\n\\\\]|\\\\(?:\\r\\n|[\\s\\S]))*", CASE_INSENSITIVE | MULTILINE), + true, + false, + "property", + grammar("inside", + token("string", pattern(compile("(#\\s*include\\s*)(?:<.+?>|(\"|')(?:\\\\?.)+?\\2)"), true)), + token("directive", pattern( + compile("(#\\s*)\\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\\b"), + true, + false, + "keyword" + )) + ) + )), + token("constant", pattern(compile("\\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\\b"))) + ); + + return c; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clike.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clike.java new file mode 100644 index 000000000000..d844ae1049e1 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clike.java @@ -0,0 +1,64 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public abstract class Prism_clike { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar( + "clike", + token( + "comment", + pattern(compile("(^|[^\\\\])\\/\\*[\\s\\S]*?(?:\\*\\/|$)"), true), + pattern(compile("(^|[^\\\\:])\\/\\/.*"), true, true) + ), + token( + "string", + pattern(compile("([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1"), false, true) + ), + token( + "class-name", + pattern( + compile("((?:\\b(?:class|interface|extends|implements|trait|instanceof|new)\\s+)|(?:catch\\s+\\())[\\w.\\\\]+"), + true, + false, + null, + grammar("inside", token("punctuation", pattern(compile("[.\\\\]")))) + ) + ), + token( + "keyword", + pattern(compile("\\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\\b")) + ), + token("boolean", pattern(compile("\\b(?:true|false)\\b"))), + token("function", pattern(compile("[a-z0-9_]+(?=\\()", Pattern.CASE_INSENSITIVE))), + token( + "number", + pattern(compile("\\b0x[\\da-f]+\\b|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:e[+-]?\\d+)?", Pattern.CASE_INSENSITIVE)) + ), + token("operator", pattern(compile("--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*|\\/|~|\\^|%"))), + token("punctuation", pattern(compile("[{}\\[\\];(),.:]"))) + ); + } + + private Prism_clike() { + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clojure.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clojure.java new file mode 100644 index 000000000000..32385226eb63 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_clojure.java @@ -0,0 +1,40 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_clojure { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("clojure", + token("comment", pattern(compile(";+.*"))), + token("string", pattern(compile("\"(?:\\\\.|[^\\\\\"\\r\\n])*\""))), + token("operator", pattern(compile("(?:::|[:|'])\\b[a-z][\\w*+!?-]*\\b", CASE_INSENSITIVE))), + token("keyword", + pattern( + compile("([^\\w+*'?-])(?:def|if|do|let|\\.\\.|quote|var|->>|->|fn|loop|recur|throw|try|monitor-enter|\\.|new|set!|def\\-|defn|defn\\-|defmacro|defmulti|defmethod|defstruct|defonce|declare|definline|definterface|defprotocol|==|defrecord|>=|deftype|<=|defproject|ns|\\*|\\+|\\-|\\/|<|=|>|accessor|agent|agent-errors|aget|alength|all-ns|alter|and|append-child|apply|array-map|aset|aset-boolean|aset-byte|aset-char|aset-double|aset-float|aset-int|aset-long|aset-short|assert|assoc|await|await-for|bean|binding|bit-and|bit-not|bit-or|bit-shift-left|bit-shift-right|bit-xor|boolean|branch\\?|butlast|byte|cast|char|children|class|clear-agent-errors|comment|commute|comp|comparator|complement|concat|conj|cons|constantly|cond|if-not|construct-proxy|contains\\?|count|create-ns|create-struct|cycle|dec|deref|difference|disj|dissoc|distinct|doall|doc|dorun|doseq|dosync|dotimes|doto|double|down|drop|drop-while|edit|end\\?|ensure|eval|every\\?|false\\?|ffirst|file-seq|filter|find|find-doc|find-ns|find-var|first|float|flush|for|fnseq|frest|gensym|get-proxy-class|get|hash-map|hash-set|identical\\?|identity|if-let|import|in-ns|inc|index|insert-child|insert-left|insert-right|inspect-table|inspect-tree|instance\\?|int|interleave|intersection|into|into-array|iterate|join|key|keys|keyword|keyword\\?|last|lazy-cat|lazy-cons|left|lefts|line-seq|list\\*|list|load|load-file|locking|long|loop|macroexpand|macroexpand-1|make-array|make-node|map|map-invert|map\\?|mapcat|max|max-key|memfn|merge|merge-with|meta|min|min-key|name|namespace|neg\\?|new|newline|next|nil\\?|node|not|not-any\\?|not-every\\?|not=|ns-imports|ns-interns|ns-map|ns-name|ns-publics|ns-refers|ns-resolve|ns-unmap|nth|nthrest|or|parse|partial|path|peek|pop|pos\\?|pr|pr-str|print|print-str|println|println-str|prn|prn-str|project|proxy|proxy-mappings|quot|rand|rand-int|range|re-find|re-groups|re-matcher|re-matches|re-pattern|re-seq|read|read-line|reduce|ref|ref-set|refer|rem|remove|remove-method|remove-ns|rename|rename-keys|repeat|replace|replicate|resolve|rest|resultset-seq|reverse|rfirst|right|rights|root|rrest|rseq|second|select|select-keys|send|send-off|seq|seq-zip|seq\\?|set|short|slurp|some|sort|sort-by|sorted-map|sorted-map-by|sorted-set|special-symbol\\?|split-at|split-with|str|string\\?|struct|struct-map|subs|subvec|symbol|symbol\\?|sync|take|take-nth|take-while|test|time|to-array|to-array-2d|tree-seq|true\\?|union|up|update-proxy|val|vals|var-get|var-set|var\\?|vector|vector-zip|vector\\?|when|when-first|when-let|when-not|with-local-vars|with-meta|with-open|with-out-str|xml-seq|xml-zip|zero\\?|zipmap|zipper)(?=[^\\w+*'?-])"), + true + ) + ), + token("boolean", pattern(compile("\\b(?:true|false|nil)\\b"))), + token("number", pattern(compile("\\b[0-9A-Fa-f]+\\b"))), + token("punctuation", pattern(compile("[{}\\[\\](),]"))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_cpp.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_cpp.java new file mode 100644 index 000000000000..01e8d93fde7b --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_cpp.java @@ -0,0 +1,50 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("c") +public class Prism_cpp { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar cpp = GrammarUtils.extend( + GrammarUtils.require(prism4j, "c"), + "cpp", + token("keyword", pattern(compile("\\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\\b"))), + token("operator", pattern(compile("--?|\\+\\+?|!=?|<{1,2}=?|>{1,2}=?|->|:{1,2}|={1,2}|\\^|~|%|&{1,2}|\\|\\|?|\\?|\\*|\\/|\\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\\b"))) + ); + + // in prism-js cpp is extending c, but c has not booleans... (like classes) + GrammarUtils.insertBeforeToken(cpp, "function", + token("boolean", pattern(compile("\\b(?:true|false)\\b"))) + ); + + GrammarUtils.insertBeforeToken(cpp, "keyword", + token("class-name", pattern(compile("(class\\s+)\\w+", CASE_INSENSITIVE), true)) + ); + + GrammarUtils.insertBeforeToken(cpp, "string", + token("raw-string", pattern(compile("R\"([^()\\\\ ]{0,16})\\([\\s\\S]*?\\)\\1\""), false, true, "string")) + ); + + return cpp; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_csharp.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_csharp.java new file mode 100644 index 000000000000..75d8bd140463 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_csharp.java @@ -0,0 +1,109 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Aliases; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Aliases("dotnet") +@Extend("clike") +public class Prism_csharp { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar classNameInsidePunctuation = grammar("inside", + token("punctuation", pattern(compile("\\."))) + ); + + final Prism4j.Grammar csharp = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "csharp", + token("keyword", pattern(compile("\\b(?:abstract|add|alias|as|ascending|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|do|double|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|from|get|global|goto|group|if|implicit|in|int|interface|internal|into|is|join|let|lock|long|namespace|new|null|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\\b"))), + token("string", + pattern(compile("@(\"|')(?:\\1\\1|\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1"), false, true), + pattern(compile("(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*?\\1"), false, true) + ), + token("class-name", + pattern( + compile("\\b[A-Z]\\w*(?:\\.\\w+)*\\b(?=\\s+\\w+)"), + false, + false, + null, + classNameInsidePunctuation + ), + pattern( + compile("(\\[)[A-Z]\\w*(?:\\.\\w+)*\\b"), + true, + false, + null, + classNameInsidePunctuation + ), + pattern( + compile("(\\b(?:class|interface)\\s+[A-Z]\\w*(?:\\.\\w+)*\\s*:\\s*)[A-Z]\\w*(?:\\.\\w+)*\\b"), + true, + false, + null, + classNameInsidePunctuation + ), + pattern( + compile("((?:\\b(?:class|interface|new)\\s+)|(?:catch\\s+\\())[A-Z]\\w*(?:\\.\\w+)*\\b"), + true, + false, + null, + classNameInsidePunctuation + ) + ), + token("number", pattern(compile("\\b0x[\\da-f]+\\b|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)f?", CASE_INSENSITIVE))) + ); + + GrammarUtils.insertBeforeToken(csharp, "class-name", + token("generic-method", pattern( + compile("\\w+\\s*<[^>\\r\\n]+?>\\s*(?=\\()"), + false, + false, + null, + grammar("inside", + token("function", pattern(compile("^\\w+"))), + token("class-name", pattern(compile("\\b[A-Z]\\w*(?:\\.\\w+)*\\b"), false, false, null, classNameInsidePunctuation)), + GrammarUtils.findToken(csharp, "keyword"), + token("punctuation", pattern(compile("[<>(),.:]"))) + ) + )), + token("preprocessor", pattern( + compile("(^\\s*)#.*", MULTILINE), + true, + false, + "property", + grammar("inside", + token("directive", pattern( + compile("(\\s*#)\\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\\b"), + true, + false, + "keyword" + )) + ) + )) + ); + + return csharp; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_css.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_css.java new file mode 100644 index 000000000000..acec49b8ae20 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_css.java @@ -0,0 +1,154 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Modify; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Modify("markup") +public abstract class Prism_css { + + // todo: really important one.. + // before a language is requested (fro example css) + // it won't be initialized (so we won't modify markup to highlight css) before it was requested... + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar grammar = grammar( + "css", + token("comment", pattern(compile("\\/\\*[\\s\\S]*?\\*\\/"))), + token( + "atrule", + pattern( + compile("@[\\w-]+?.*?(?:;|(?=\\s*\\{))", CASE_INSENSITIVE), + false, + false, + null, + grammar( + "inside", + token("rule", pattern(compile("@[\\w-]+"))) + ) + ) + ), + token( + "url", + pattern(compile("url\\((?:([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1|.*?)\\)", CASE_INSENSITIVE)) + ), + token("selector", pattern(compile("[^{}\\s][^{};]*?(?=\\s*\\{)"))), + token( + "string", + pattern(compile("(\"|')(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1"), false, true) + ), + token( + "property", + pattern(compile("[-_a-z\\xA0-\\uFFFF][-\\w\\xA0-\\uFFFF]*(?=\\s*:)", CASE_INSENSITIVE)) + ), + token("important", pattern(compile("\\B!important\\b", CASE_INSENSITIVE))), + token("function", pattern(compile("[-a-z0-9]+(?=\\()", CASE_INSENSITIVE))), + token("punctuation", pattern(compile("[(){};:]"))) + ); + + // can we maybe add some helper to specify simplified location? + + // now we need to put the all tokens from grammar inside `atrule` (except the `atrule` of cause) + final Prism4j.Token atrule = grammar.tokens().get(1); + final Prism4j.Grammar inside = GrammarUtils.findFirstInsideGrammar(atrule); + if (inside != null) { + for (Prism4j.Token token : grammar.tokens()) { + if (!"atrule".equals(token.name())) { + inside.tokens().add(token); + } + } + } + + final Prism4j.Grammar markup = prism4j.grammar("markup"); + if (markup != null) { + GrammarUtils.insertBeforeToken(markup, "tag", + token( + "style", + pattern( + compile("()[\\s\\S]*?(?=<\\/style>)", CASE_INSENSITIVE), + true, + true, + "language-css", + grammar + ) + ) + ); + + // important thing here is to clone found grammar + // otherwise we will have stackoverflow (inside tag references style-attr, which + // references inside tag, etc) + final Prism4j.Grammar markupTagInside; + { + Prism4j.Grammar _temp = null; + final Prism4j.Token token = GrammarUtils.findToken(markup, "tag"); + if (token != null) { + _temp = GrammarUtils.findFirstInsideGrammar(token); + if (_temp != null) { + _temp = GrammarUtils.clone(_temp); + } + } + markupTagInside = _temp; + } + + GrammarUtils.insertBeforeToken(markup, "tag/attr-value", + token( + "style-attr", + pattern( + compile("\\s*style=(\"|')(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1", CASE_INSENSITIVE), + false, + false, + "language-css", + grammar( + "inside", + token( + "attr-name", + pattern( + compile("^\\s*style", CASE_INSENSITIVE), + false, + false, + null, + markupTagInside + ) + ), + token("punctuation", pattern(compile("^\\s*=\\s*['\"]|['\"]\\s*$"))), + token( + "attr-value", + pattern( + compile(".+", CASE_INSENSITIVE), + false, + false, + null, + grammar + ) + ) + + ) + ) + ) + ); + } + + return grammar; + } + + private Prism_css() { + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_dart.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_dart.java new file mode 100644 index 000000000000..6ab0ad70dc43 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_dart.java @@ -0,0 +1,47 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_dart { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar dart = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "dart", + token("string", + pattern(compile("r?(\"\"\"|''')[\\s\\S]*?\\1"), false, true), + pattern(compile("r?(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1"), false, true) + ), + token("keyword", + pattern(compile("\\b(?:async|sync|yield)\\*")), + pattern(compile("\\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\\b")) + ), + token("operator", pattern(compile("\\bis!|\\b(?:as|is)\\b|\\+\\+|--|&&|\\|\\||<<=?|>>=?|~(?:\\/=?)?|[+\\-*\\/%&^|=!<>]=?|\\?"))) + ); + + GrammarUtils.insertBeforeToken(dart, "function", + token("metadata", pattern(compile("@\\w+"), false, false, "symbol")) + ); + + return dart; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_git.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_git.java new file mode 100644 index 000000000000..4a37dafe6be9 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_git.java @@ -0,0 +1,43 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_git { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("git", + token("comment", pattern(compile("^#.*", MULTILINE))), + token("deleted", pattern(compile("^[-–].*", MULTILINE))), + token("inserted", pattern(compile("^\\+.*", MULTILINE))), + token("string", pattern(compile("(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1", MULTILINE))), + token("command", pattern( + compile("^.*\\$ git .*$", MULTILINE), + false, + false, + null, + grammar("inside", + token("parameter", pattern(compile("\\s--?\\w+", MULTILINE))) + ) + )), + token("coord", pattern(compile("^@@.*@@$", MULTILINE))), + token("commit_sha1", pattern(compile("^commit \\w{40}$", MULTILINE))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_go.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_go.java new file mode 100644 index 000000000000..b400a27257f6 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_go.java @@ -0,0 +1,55 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_go { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar go = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "go", + new GrammarUtils.TokenFilter() { + @Override + public boolean test(@NotNull Prism4j.Token token) { + return !"class-name".equals(token.name()); + } + }, + token("keyword", pattern(compile("\\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\\b"))), + token("boolean", pattern(compile("\\b(?:_|iota|nil|true|false)\\b"))), + token("operator", pattern(compile("[*\\/%^!=]=?|\\+[=+]?|-[=-]?|\\|[=|]?|&(?:=|&|\\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\\.\\.\\."))), + token("number", pattern(compile("(?:\\b0x[a-f\\d]+|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:e[-+]?\\d+)?)i?", CASE_INSENSITIVE))), + token("string", pattern( + compile("([\"'`])(\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1"), + false, + true + )) + ); + + // clike doesn't have builtin + GrammarUtils.insertBeforeToken(go, "boolean", + token("builtin", pattern(compile("\\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\\b"))) + ); + + return go; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_groovy.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_groovy.java new file mode 100644 index 000000000000..93909fa6592d --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_groovy.java @@ -0,0 +1,84 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_groovy { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar groovy = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "groovy", + token("keyword", pattern(compile("\\b(?:as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\\b"))), + token("string", + pattern( + compile("(\"\"\"|''')[\\s\\S]*?\\1|(?:\\$\\/)(?:\\$\\/\\$|[\\s\\S])*?\\/\\$"), false, true + ), + pattern( + compile("([\"'\\/])(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1"), false, true + ) + ), + token("number", + pattern( + compile("\\b(?:0b[01_]+|0x[\\da-f_]+(?:\\.[\\da-f_p\\-]+)?|[\\d_]+(?:\\.[\\d_]+)?(?:e[+-]?[\\d]+)?)[glidf]?\\b", CASE_INSENSITIVE) + ) + ), + token("operator", + pattern( + compile("(^|[^.])(?:~|==?~?|\\?[.:]?|\\*(?:[.=]|\\*=?)?|\\.[@&]|\\.\\.<|\\.{1,2}(?!\\.)|-[-=>]?|\\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\\|[|=]?|\\/=?|\\^=?|%=?)"), + true + ) + ), + token("punctuation", + pattern(compile("\\.+|[{}\\[\\];(),:$]")) + ) + ); + + GrammarUtils.insertBeforeToken(groovy, "string", + token("shebang", pattern( + compile("#!.+"), + false, + false, + "comment" + )) + ); + + GrammarUtils.insertBeforeToken(groovy, "punctuation", + token("spock-block", pattern( + compile("\\b(?:setup|given|when|then|and|cleanup|expect|where):") + )) + ); + + GrammarUtils.insertBeforeToken(groovy, "function", + token("annotation", pattern( + compile("(^|[^.])@\\w+"), + true, + false, + "punctuation" + )) + ); + + // no string templates :( + + return groovy; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_java.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_java.java new file mode 100644 index 000000000000..35197233df85 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_java.java @@ -0,0 +1,66 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_java { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Token keyword = token("keyword", pattern(compile("\\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\\b"))); + + final Prism4j.Grammar java = GrammarUtils.extend(GrammarUtils.require(prism4j, "clike"), "java", + keyword, + token("number", pattern(compile("\\b0b[01]+\\b|\\b0x[\\da-f]*\\.?[\\da-fp-]+\\b|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:e[+-]?\\d+)?[df]?", CASE_INSENSITIVE))), + token("operator", pattern( + compile("(^|[^.])(?:\\+[+=]?|-[-=]?|!=?|<>?>?=?|==?|&[&=]?|\\|[|=]?|\\*=?|\\/=?|%=?|\\^=?|[?:~])", MULTILINE), + true + )) + ); + + GrammarUtils.insertBeforeToken(java, "function", + token("annotation", pattern( + compile("(^|[^.])@\\w+"), + true, + false, + "punctuation" + )) + ); + + GrammarUtils.insertBeforeToken(java, "class-name", + token("generics", pattern( + compile("<\\s*\\w+(?:\\.\\w+)?(?:\\s*,\\s*\\w+(?:\\.\\w+)?)*>", CASE_INSENSITIVE), + false, + false, + "function", + grammar( + "inside", + keyword, + token("punctuation", pattern(compile("[<>(),.:]"))) + ) + )) + ); + + return java; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_javascript.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_javascript.java new file mode 100644 index 000000000000..854760c08aa5 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_javascript.java @@ -0,0 +1,116 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Aliases; +import io.noties.prism4j.annotations.Extend; +import io.noties.prism4j.annotations.Modify; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Aliases("js") +@Modify("markup") +@Extend("clike") +public class Prism_javascript { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar js = GrammarUtils.extend(GrammarUtils.require(prism4j, "clike"), "javascript", + token("keyword", pattern(compile("\\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\\b"))), + token("number", pattern(compile("\\b(?:0[xX][\\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\\b|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:[Ee][+-]?\\d+)?"))), + token("function", pattern(compile("[_$a-z\\xA0-\\uFFFF][$\\w\\xA0-\\uFFFF]*(?=\\s*\\()", CASE_INSENSITIVE))), + token("operator", pattern(compile("-[-=]?|\\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\\|[|=]?|\\*\\*?=?|\\/=?|~|\\^=?|%=?|\\?|\\.{3}"))) + ); + + GrammarUtils.insertBeforeToken(js, "keyword", + token("regex", pattern( + compile("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s])\\s*)\\/(\\[[^\\]\\r\\n]+]|\\\\.|[^/\\\\\\[\\r\\n])+\\/[gimyu]{0,5}(?=\\s*($|[\\r\\n,.;})\\]]))"), + true, + true + )), + token( + "function-variable", + pattern( + compile("[_$a-z\\xA0-\\uFFFF][$\\w\\xA0-\\uFFFF]*(?=\\s*=\\s*(?:function\\b|(?:\\([^()]*\\)|[_$a-z\\xA0-\\uFFFF][$\\w\\xA0-\\uFFFF]*)\\s*=>))", CASE_INSENSITIVE), + false, + false, + "function" + ) + ), + token("constant", pattern(compile("\\b[A-Z][A-Z\\d_]*\\b"))) + ); + + final Prism4j.Token interpolation = token("interpolation"); + + GrammarUtils.insertBeforeToken(js, "string", + token( + "template-string", + pattern( + compile("`(?:\\\\[\\s\\S]|\\$\\{[^}]+\\}|[^\\\\`])*`"), + false, + true, + null, + grammar( + "inside", + interpolation, + token("string", pattern(compile("[\\s\\S]+"))) + ) + ) + ) + ); + + final Prism4j.Grammar insideInterpolation; + { + final List tokens = new ArrayList<>(js.tokens().size() + 1); + tokens.add(token( + "interpolation-punctuation", + pattern(compile("^\\$\\{|\\}$"), false, false, "punctuation") + )); + tokens.addAll(js.tokens()); + insideInterpolation = grammar("inside", tokens); + } + + interpolation.patterns().add(pattern( + compile("\\$\\{[^}]+\\}"), + false, + false, + null, + insideInterpolation + )); + + final Prism4j.Grammar markup = prism4j.grammar("markup"); + if (markup != null) { + GrammarUtils.insertBeforeToken(markup, "tag", + token( + "script", pattern( + compile("()[\\s\\S]*?(?=<\\/script>)", CASE_INSENSITIVE), + true, + true, + "language-javascript", + js + ) + ) + ); + } + + return js; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_json.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_json.java new file mode 100644 index 000000000000..aa2f49ef9f1b --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_json.java @@ -0,0 +1,39 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Aliases; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Aliases("jsonp") +public class Prism_json { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar( + "json", + token("property", pattern(compile("\"(?:\\\\.|[^\\\\\"\\r\\n])*\"(?=\\s*:)", CASE_INSENSITIVE))), + token("string", pattern(compile("\"(?:\\\\.|[^\\\\\"\\r\\n])*\"(?!\\s*:)"), false, true)), + token("number", pattern(compile("\\b0x[\\dA-Fa-f]+\\b|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:[Ee][+-]?\\d+)?"))), + token("punctuation", pattern(compile("[{}\\[\\]);,]"))), + // not sure about this one... + token("operator", pattern(compile(":"))), + token("boolean", pattern(compile("\\b(?:true|false)\\b", CASE_INSENSITIVE))), + token("null", pattern(compile("\\bnull\\b", CASE_INSENSITIVE))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_kotlin.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_kotlin.java new file mode 100644 index 000000000000..f2221a804c42 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_kotlin.java @@ -0,0 +1,121 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.compile; + + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_kotlin { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar kotlin = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "kotlin", + new GrammarUtils.TokenFilter() { + @Override + public boolean test(@NotNull Prism4j.Token token) { + return !"class-name".equals(token.name()); + } + }, + token( + "keyword", + pattern(compile("(^|[^.])\\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\\b"), true) + ), + token( + "function", + pattern(compile("\\w+(?=\\s*\\()")), + pattern(compile("(\\.)\\w+(?=\\s*\\{)"), true) + ), + token( + "number", + pattern(compile("\\b(?:0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\\d+(?:_\\d+)*(?:\\.\\d+(?:_\\d+)*)?(?:[eE][+-]?\\d+(?:_\\d+)*)?[fFL]?)\\b")) + ), + token( + "operator", + pattern(compile("\\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\\/*%<>]=?|[?:]:?|\\.\\.|&&|\\|\\||\\b(?:and|inv|or|shl|shr|ushr|xor)\\b")) + ) + ); + + GrammarUtils.insertBeforeToken(kotlin, "string", + token("raw-string", pattern(compile("(\"\"\"|''')[\\s\\S]*?\\1"), false, false, "string")) + ); + + GrammarUtils.insertBeforeToken(kotlin, "keyword", + token("annotation", pattern(compile("\\B@(?:\\w+:)?(?:[A-Z]\\w*|\\[[^\\]]+\\])"), false, false, "builtin")) + ); + + GrammarUtils.insertBeforeToken(kotlin, "function", + token("label", pattern(compile("\\w+@|@\\w+"), false, false, "symbol")) + ); + + // this grammar has 1 token: interpolation, which has 2 patterns + final Prism4j.Grammar interpolationInside; + { + + // okay, I was cloning the tokens of kotlin grammar (so there is no recursive chain of calls), + // but it looks like it wants to have recursive calls + // I did this because interpolation test was failing due to the fact that `string` + // `raw-string` tokens didn't have `inside`, so there were not tokenized + // I still find that it has potential to fall with stackoverflow (in some cases) + final List tokens = new ArrayList<>(kotlin.tokens().size() + 1); + tokens.add(token("delimiter", pattern(compile("^\\$\\{|\\}$"), false, false, "variable"))); + tokens.addAll(kotlin.tokens()); + + interpolationInside = grammar( + "inside", + token("interpolation", + pattern(compile("\\$\\{[^}]+\\}"), false, false, null, grammar("inside", tokens)), + pattern(compile("\\$\\w+"), false, false, "variable") + ) + ); + } + + final Prism4j.Token string = GrammarUtils.findToken(kotlin, "string"); + final Prism4j.Token rawString = GrammarUtils.findToken(kotlin, "raw-string"); + + if (string != null + && rawString != null) { + + final Prism4j.Pattern stringPattern = string.patterns().get(0); + final Prism4j.Pattern rawStringPattern = rawString.patterns().get(0); + + string.patterns().add( + pattern(stringPattern.regex(), stringPattern.lookbehind(), stringPattern.greedy(), stringPattern.alias(), interpolationInside) + ); + + rawString.patterns().add( + pattern(rawStringPattern.regex(), rawStringPattern.lookbehind(), rawStringPattern.greedy(), rawStringPattern.alias(), interpolationInside) + ); + + string.patterns().remove(0); + rawString.patterns().remove(0); + + } else { + throw new RuntimeException("Unexpected state, cannot find `string` and/or `raw-string` tokens " + + "inside kotlin grammar"); + } + + return kotlin; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_latex.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_latex.java new file mode 100644 index 000000000000..d4493e924777 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_latex.java @@ -0,0 +1,81 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_latex { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Pattern funcPattern = compile("\\\\(?:[^a-z()\\[\\]]|[a-z*]+)", CASE_INSENSITIVE); + + final Prism4j.Grammar insideEqu = grammar("inside", + token("equation-command", pattern(funcPattern, false, false, "regex")) + ); + + return grammar("latex", + token("comment", pattern(compile("%.*", MULTILINE))), + token("cdata", pattern( + compile("(\\\\begin\\{((?:verbatim|lstlisting)\\*?)\\})[\\s\\S]*?(?=\\\\end\\{\\2\\})"), + true + ) + ), + token("equation", + pattern( + compile("\\$(?:\\\\[\\s\\S]|[^\\\\$])*\\$|\\\\\\([\\s\\S]*?\\\\\\)|\\\\\\[[\\s\\S]*?\\\\\\]"), + false, + false, + "string", + insideEqu + ), + pattern( + compile("(\\\\begin\\{((?:equation|math|eqnarray|align|multline|gather)\\*?)\\})[\\s\\S]*?(?=\\\\end\\{\\2\\})"), + true, + false, + "string", + insideEqu + ) + ), + token("keyword", pattern( + compile("(\\\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\\[[^\\]]+\\])?\\{)[^}]+(?=\\})"), + true + )), + token("url", pattern( + compile("(\\\\url\\{)[^}]+(?=\\})"), + true + )), + token("headline", pattern( + compile("(\\\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\\*?(?:\\[[^\\]]+\\])?\\{)[^}]+(?=\\}(?:\\[[^\\]]+\\])?)"), + true, + false, + "class-name" + )), + token("function", pattern( + funcPattern, + false, + false, + "selector" + )), + token("punctuation", pattern(compile("[\\[\\]{}&]"))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_makefile.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_makefile.java new file mode 100644 index 000000000000..bb6e6d7212df --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_makefile.java @@ -0,0 +1,57 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_makefile { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("makefile", + token("comment", pattern( + compile("(^|[^\\\\])#(?:\\\\(?:\\r\\n|[\\s\\S])|[^\\\\\\r\\n])*"), + true + )), + token("string", pattern( + compile("([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1"), + false, + true + )), + token("builtin", pattern(compile("\\.[A-Z][^:#=\\s]+(?=\\s*:(?!=))"))), + token("symbol", pattern( + compile("^[^:=\\r\\n]+(?=\\s*:(?!=))", MULTILINE), + false, + false, + null, + grammar("inside", + token("variable", pattern(compile("\\$+(?:[^(){}:#=\\s]+|(?=[({]))"))) + ) + )), + token("variable", pattern(compile("\\$+(?:[^(){}:#=\\s]+|\\([@*%<^+?][DF]\\)|(?=[({]))"))), + token("keyword", + pattern(compile("-include\\b|\\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\\b")), + pattern( + compile("(\\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \\t])"), + true + ) + ), + token("operator", pattern(compile("(?:::|[?:+!])?=|[|@]"))), + token("punctuation", pattern(compile("[:;(){}]"))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markdown.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markdown.java new file mode 100644 index 000000000000..c1fed9144e4e --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markdown.java @@ -0,0 +1,125 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("markup") +public class Prism_markdown { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar markdown = GrammarUtils.extend( + GrammarUtils.require(prism4j, "markup"), + "markdown" + ); + + final Prism4j.Token bold = token("bold", pattern( + compile("(^|[^\\\\])(\\*\\*|__)(?:(?:\\r?\\n|\\r)(?!\\r?\\n|\\r)|.)+?\\2"), + true, + false, + null, + grammar("inside", token("punctuation", pattern(compile("^\\*\\*|^__|\\*\\*$|__$")))) + )); + + final Prism4j.Token italic = token("italic", pattern( + compile("(^|[^\\\\])([*_])(?:(?:\\r?\\n|\\r)(?!\\r?\\n|\\r)|.)+?\\2"), + true, + false, + null, + grammar("inside", token("punctuation", pattern(compile("^[*_]|[*_]$")))) + )); + + final Prism4j.Token url = token("url", pattern( + compile("!?\\[[^\\]]+\\](?:\\([^\\s)]+(?:[\\t ]+\"(?:\\\\.|[^\"\\\\])*\")?\\)| ?\\[[^\\]\\n]*\\])"), + false, + false, + null, + grammar("inside", + token("variable", pattern(compile("(!?\\[)[^\\]]+(?=\\]$)"), true)), + token("string", pattern(compile("\"(?:\\\\.|[^\"\\\\])*\"(?=\\)$)"))) + ) + )); + + GrammarUtils.insertBeforeToken(markdown, "prolog", + token("blockquote", pattern(compile("^>(?:[\\t ]*>)*", MULTILINE))), + token("code", + pattern(compile("^(?: {4}|\\t).+", MULTILINE), false, false, "keyword"), + pattern(compile("``.+?``|`[^`\\n]+`"), false, false, "keyword") + ), + token( + "title", + pattern( + compile("\\w+.*(?:\\r?\\n|\\r)(?:==+|--+)"), + false, + false, + "important", + grammar("inside", token("punctuation", pattern(compile("==+$|--+$")))) + ), + pattern( + compile("(^\\s*)#+.+", MULTILINE), + true, + false, + "important", + grammar("inside", token("punctuation", pattern(compile("^#+|#+$")))) + ) + ), + token("hr", pattern( + compile("(^\\s*)([*-])(?:[\\t ]*\\2){2,}(?=\\s*$)", MULTILINE), + true, + false, + "punctuation" + )), + token("list", pattern( + compile("(^\\s*)(?:[*+-]|\\d+\\.)(?=[\\t ].)", MULTILINE), + true, + false, + "punctuation" + )), + token("url-reference", pattern( + compile("!?\\[[^\\]]+\\]:[\\t ]+(?:\\S+|<(?:\\\\.|[^>\\\\])+>)(?:[\\t ]+(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\((?:\\\\.|[^)\\\\])*\\)))?"), + false, + false, + "url", + grammar("inside", + token("variable", pattern(compile("^(!?\\[)[^\\]]+"), true)), + token("string", pattern(compile("(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\((?:\\\\.|[^)\\\\])*\\))$"))), + token("punctuation", pattern(compile("^[\\[\\]!:]|[<>]"))) + ) + )), + bold, + italic, + url + ); + + add(GrammarUtils.findFirstInsideGrammar(bold), url, italic); + add(GrammarUtils.findFirstInsideGrammar(italic), url, bold); + + return markdown; + } + + private static void add(@Nullable Prism4j.Grammar grammar, @NotNull Prism4j.Token first, @NotNull Prism4j.Token second) { + if (grammar != null) { + grammar.tokens().add(first); + grammar.tokens().add(second); + } + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markup.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markup.java new file mode 100644 index 000000000000..a68b2c4eab4e --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_markup.java @@ -0,0 +1,99 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Aliases; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Aliases({"xml", "html", "mathml", "svg"}) +public abstract class Prism_markup { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + final Prism4j.Token entity = token("entity", pattern(compile("&#?[\\da-z]{1,8};", Pattern.CASE_INSENSITIVE))); + return grammar( + "markup", + token("comment", pattern(compile(""))), + token("prolog", pattern(compile("<\\?[\\s\\S]+?\\?>"))), + token("doctype", pattern(compile("", Pattern.CASE_INSENSITIVE))), + token("cdata", pattern(compile("", Pattern.CASE_INSENSITIVE))), + token( + "tag", + pattern( + compile("<\\/?(?!\\d)[^\\s>\\/=$<%]+(?:\\s+[^\\s>\\/=]+(?:=(?:(\"|')(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1|[^\\s'\">=]+))?)*\\s*\\/?>", Pattern.CASE_INSENSITIVE), + false, + true, + null, + grammar( + "inside", + token( + "tag", + pattern( + compile("^<\\/?[^\\s>\\/]+", Pattern.CASE_INSENSITIVE), + false, + false, + null, + grammar( + "inside", + token("punctuation", pattern(compile("^<\\/?"))), + token("namespace", pattern(compile("^[^\\s>\\/:]+:"))) + ) + ) + ), + token( + "attr-value", + pattern( + compile("=(?:(\"|')(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1|[^\\s'\">=]+)", Pattern.CASE_INSENSITIVE), + false, + false, + null, + grammar( + "inside", + token( + "punctuation", + pattern(compile("^=")), + pattern(compile("(^|[^\\\\])[\"']"), true) + ), + entity + ) + ) + ), + token("punctuation", pattern(compile("\\/?>"))), + token( + "attr-name", + pattern( + compile("[^\\s>\\/]+"), + false, + false, + null, + grammar( + "inside", + token("namespace", pattern(compile("^[^\\s>\\/:]+:"))) + ) + ) + ) + ) + ) + ), + entity + ); + } + + private Prism_markup() { + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_python.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_python.java new file mode 100644 index 000000000000..5fa559e78c9d --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_python.java @@ -0,0 +1,59 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_python { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("python", + token("comment", pattern( + compile("(^|[^\\\\])#.*"), + true + )), + token("triple-quoted-string", pattern( + compile("(\"\"\"|''')[\\s\\S]+?\\1"), + false, + true, + "string" + )), + token("string", pattern( + compile("(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1"), + false, + true + )), + token("function", pattern( + compile("((?:^|\\s)def[ \\t]+)[a-zA-Z_]\\w*(?=\\s*\\()"), + true + )), + token("class-name", pattern( + compile("(\\bclass\\s+)\\w+", CASE_INSENSITIVE), + true + )), + token("keyword", pattern(compile("\\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|pass|print|raise|return|try|while|with|yield)\\b"))), + token("builtin", pattern(compile("\\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\\b"))), + token("boolean", pattern(compile("\\b(?:True|False|None)\\b"))), + token("number", pattern( + compile("(?:\\b(?=\\d)|\\B(?=\\.))(?:0[bo])?(?:(?:\\d|0x[\\da-f])[\\da-f]*\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?j?\\b", CASE_INSENSITIVE) + )), + token("operator", pattern(compile("[-+%=]=?|!=|\\*\\*?=?|\\/\\/?=?|<[<=>]?|>[=>]?|[&|^~]|\\b(?:or|and|not)\\b"))), + token("punctuation", pattern(compile("[{}\\[\\];(),.:]"))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_scala.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_scala.java new file mode 100644 index 000000000000..6034a426399e --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_scala.java @@ -0,0 +1,59 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +@Extend("java") +public class Prism_scala { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + final Prism4j.Grammar scala = GrammarUtils.extend( + GrammarUtils.require(prism4j, "java"), + "scala", + new GrammarUtils.TokenFilter() { + @Override + public boolean test(@NotNull Prism4j.Token token) { + final String name = token.name(); + return !"class-name".equals(name) && !"function".equals(name); + } + }, + token("keyword", pattern( + compile("<-|=>|\\b(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\\b") + )), + token("string", + pattern(compile("\"\"\"[\\s\\S]*?\"\"\""), false, true), + pattern(compile("(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1"), false, true) + ), + token("number", pattern( + compile("\\b0x[\\da-f]*\\.?[\\da-f]+|(?:\\b\\d+\\.?\\d*|\\B\\.\\d+)(?:e\\d+)?[dfl]?", CASE_INSENSITIVE) + )) + ); + + scala.tokens().add( + token("symbol", pattern(compile("'[^\\d\\s\\\\]\\w*"))) + ); + + GrammarUtils.insertBeforeToken(scala, "number", + token("builtin", pattern(compile("\\b(?:String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\\b"))) + ); + + return scala; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_sql.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_sql.java new file mode 100644 index 000000000000..edab1678003d --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_sql.java @@ -0,0 +1,54 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_sql { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("sql", + token("comment", pattern( + compile("(^|[^\\\\])(?:\\/\\*[\\s\\S]*?\\*\\/|(?:--|\\/\\/|#).*)"), + true + )), + token("string", pattern( + compile("(^|[^@\\\\])(\"|')(?:\\\\[\\s\\S]|(?!\\2)[^\\\\])*\\2"), + true, + true + )), + token("variable", pattern(compile("@[\\w.$]+|@([\"'`])(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])+\\1"))), + token("function", pattern( + compile("\\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\\s*\\()", CASE_INSENSITIVE) + )), + token("keyword", pattern( + compile("\\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\\b", CASE_INSENSITIVE) + )), + token("boolean", pattern( + compile("\\b(?:TRUE|FALSE|NULL)\\b", CASE_INSENSITIVE) + )), + token("number", pattern( + compile("\\b0x[\\da-f]+\\b|\\b\\d+\\.?\\d*|\\B\\.\\d+\\b", CASE_INSENSITIVE) + )), + token("operator", pattern( + compile("[-+*\\/=%^~]|&&?|\\|\\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\\b", CASE_INSENSITIVE) + )), + token("punctuation", pattern(compile("[;\\[\\]()`,.]"))) + ); + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_swift.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_swift.java new file mode 100644 index 000000000000..34f98b725438 --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_swift.java @@ -0,0 +1,77 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import io.noties.prism4j.GrammarUtils; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.Extend; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.compile; + + +@SuppressWarnings("unused") +@Extend("clike") +public class Prism_swift { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + + final Prism4j.Grammar swift = GrammarUtils.extend( + GrammarUtils.require(prism4j, "clike"), + "swift", + token("string", pattern( + compile("(\"|')(\\\\(?:\\((?:[^()]|\\([^)]+\\))+\\)|\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1"), + false, + true, + null, + grammar("inside", token("interpolation", pattern( + compile("\\\\\\((?:[^()]|\\([^)]+\\))+\\)"), + false, + false, + null, + grammar("inside", token("delimiter", pattern( + compile("^\\\\\\(|\\)$"), + false, + false, + "variable" + ))) + ))) + )), + token("keyword", pattern( + compile("\\b(?:as|associativity|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\\b") + )), + token("number", pattern( + compile("\\b(?:[\\d_]+(?:\\.[\\de_]+)?|0x[a-f0-9_]+(?:\\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b", CASE_INSENSITIVE) + )) + ); + + final List tokens = swift.tokens(); + + tokens.add(token("constant", pattern(compile("\\b(?:nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\\b")))); + tokens.add(token("atrule", pattern(compile("@\\b(?:IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|noreturn|NS(?:Copying|Managed)|objc|UIApplicationMain|auto_closure)\\b")))); + tokens.add(token("builtin", pattern(compile("\\b(?:[A-Z]\\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\\b")))); + + final Prism4j.Token interpolationToken = GrammarUtils.findToken(swift, "string/interpolation"); + final Prism4j.Grammar interpolationGrammar = interpolationToken != null + ? GrammarUtils.findFirstInsideGrammar(interpolationToken) + : null; + if (interpolationGrammar != null) { + interpolationGrammar.tokens().addAll(swift.tokens()); + } + + return swift; + } +} diff --git a/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_yaml.java b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_yaml.java new file mode 100644 index 000000000000..31e3fcb86e3b --- /dev/null +++ b/app/src/main/java/third_parties/io/noties/prism4j/languages/Prism_yaml.java @@ -0,0 +1,78 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package third_parties.io.noties.prism4j.languages; + +import org.jetbrains.annotations.NotNull; + +import io.noties.prism4j.Prism4j; + +import static io.noties.prism4j.Prism4j.grammar; +import static io.noties.prism4j.Prism4j.pattern; +import static io.noties.prism4j.Prism4j.token; +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static java.util.regex.Pattern.MULTILINE; +import static java.util.regex.Pattern.compile; + +@SuppressWarnings("unused") +public class Prism_yaml { + + @NotNull + public static Prism4j.Grammar create(@NotNull Prism4j prism4j) { + return grammar("yaml", + token("scalar", pattern( + compile("([\\-:]\\s*(?:![^\\s]+)?[ \\t]*[|>])[ \\t]*(?:((?:\\r?\\n|\\r)[ \\t]+)[^\\r\\n]+(?:\\2[^\\r\\n]+)*)"), + true, + false, + "string" + )), + token("comment", pattern(compile("#.*"))), + token("key", pattern( + compile("(\\s*(?:^|[:\\-,\\[{\\r\\n?])[ \\t]*(?:![^\\s]+)?[ \\t]*)[^\\r\\n{\\[\\]},#\\s]+?(?=\\s*:\\s)"), + true, + false, + "atrule" + )), + token("directive", pattern( + compile("(^[ \\t]*)%.+", MULTILINE), + true, + false, + "important" + )), + token("datetime", pattern( + compile("([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \\t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \\t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?)(?=[ \\t]*(?:$|,|]|\\}))", MULTILINE), + true, + false, + "number" + )), + token("boolean", pattern( + compile("([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:true|false)[ \\t]*(?=$|,|]|\\})", MULTILINE | CASE_INSENSITIVE), + true, + false, + "important" + )), + token("null", pattern( + compile("([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:null|~)[ \\t]*(?=$|,|]|\\})", MULTILINE | CASE_INSENSITIVE), + true, + false, + "important" + )), + token("string", pattern( + compile("([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(\"|')(?:(?!\\2)[^\\\\\\r\\n]|\\\\.)*\\2(?=[ \\t]*(?:$|,|]|\\}))", MULTILINE), + true, + true + )), + token("number", pattern( + compile("([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)[ \\t]*(?=$|,|]|\\})", MULTILINE | CASE_INSENSITIVE), + true + )), + token("tag", pattern(compile("![^\\s]+"))), + token("important", pattern(compile("[&*][\\w]+"))), + token("punctuation", pattern(compile("---|[:\\[\\]{}\\-,|>?]|\\.\\.\\."))) + ); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 75f16a6b6ae1..58549bc5001a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,6 @@ plugins { alias(libs.plugins.jetbrains.kotlin.android) apply false alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.spotless) apply false - alias(libs.plugins.kapt) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.kotlin.parcelize) apply false diff --git a/gradle.properties b/gradle.properties index 50cc48359122..76705948bed8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,7 +17,6 @@ kotlin.daemon.jvmargs=-Xmx6144m -XX:+UseParallelGC org.gradle.caching=true org.gradle.parallel=true org.gradle.configureondemand=true -kapt.incremental.apt=true org.gradle.daemon=true org.gradle.configuration-cache=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bcbefe2483ae..4a7098394db4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -284,7 +284,6 @@ spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugsGradlePlugin" } jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } -kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin" } shot = { id = "shot", version.ref = "shotVersion" }