From 1640456049cda9999bb27501af30e05e46b0360d Mon Sep 17 00:00:00 2001 From: sigoden Date: Tue, 7 Mar 2023 11:38:44 +0800 Subject: [PATCH] refactor: use syntect for highlight, abandon mdcat (#26) * refactor: use syntect for highlight, abandon mdcat * split src/render.rs to sub modules. embed a default theme * simulate typing effect. * fix format --- Cargo.lock | 918 +------------ Cargo.toml | 5 +- src/main.rs | 4 +- src/render.rs | 91 -- src/render/markdown.rs | 150 +++ src/render/mod.rs | 120 ++ src/render/theme.yaml | 2846 ++++++++++++++++++++++++++++++++++++++++ src/repl/handler.rs | 8 +- 8 files changed, 3133 insertions(+), 1009 deletions(-) delete mode 100644 src/render.rs create mode 100644 src/render/markdown.rs create mode 100644 src/render/mod.rs create mode 100644 src/render/theme.yaml diff --git a/Cargo.lock b/Cargo.lock index 9a7c5b5..b5422ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,8 +34,6 @@ dependencies = [ "futures-util", "inquire", "is-terminal", - "mdcat", - "pulldown-cmark", "reedline", "reqwest", "serde", @@ -43,21 +41,7 @@ dependencies = [ "serde_yaml", "syntect", "tokio", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", + "unicode-width", ] [[package]] @@ -69,53 +53,18 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "async-compression" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - [[package]] name = "atty" version = "0.2.14" @@ -163,12 +112,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - [[package]] name = "bitflags" version = "1.3.2" @@ -181,45 +124,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "brotli" -version = "3.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bumpalo" version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" -[[package]] -name = "bytemuck" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" version = "1.4.0" @@ -268,15 +178,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "clap_complete" -version = "4.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501ff0a401473ea1d4c3b125ff95506b62c5bc5768d818634195fbb7c4ad5ff4" -dependencies = [ - "clap", -] - [[package]] name = "clap_derive" version = "4.1.8" @@ -319,12 +220,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "copypasta" version = "0.8.2" @@ -339,16 +234,6 @@ dependencies = [ "x11-clipboard", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -489,12 +374,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "cxx" version = "1.0.92" @@ -539,12 +418,6 @@ dependencies = [ "syn", ] -[[package]] -name = "data-url" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" - [[package]] name = "dirs" version = "4.0.0" @@ -601,16 +474,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "env_proxy" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5019be18538406a43b5419a5501461f0c8b49ea7dfda0cfc32f4e51fc44be1" -dependencies = [ - "log", - "url", -] - [[package]] name = "errno" version = "0.2.8" @@ -643,22 +506,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "exr" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8af5ef47e2ed89d23d0ecbc1b681b30390069de70260937877514377fc24feb" -dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide", - "smallvec", - "threadpool", - "zune-inflate", -] - [[package]] name = "fancy-regex" version = "0.7.1" @@ -677,7 +524,7 @@ checksum = "8ef1a30ae415c3a691a4f41afddc2dbcd6d70baf338368d85ebc1e8ed92cedb9" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -690,52 +537,12 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" - -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin 0.9.5", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "fontconfig-parser" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab2e12762761366dcb876ab8b6e0cfa4797ddcd890575919f008b5ba655672a" -dependencies = [ - "roxmltree", -] - -[[package]] -name = "fontdb" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff20bef7942a72af07104346154a70a70b089c572e454b41bef6eb6cb10e9c06" -dependencies = [ - "fontconfig-parser", - "log", - "memmap2", - "ttf-parser", -] - [[package]] name = "form_urlencoded" version = "1.1.0" @@ -816,16 +623,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "gethostname" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a329e22866dd78b35d2c639a4a23d7b950aeae300dfd79f4fb19f74055c2404" -dependencies = [ - "libc", - "windows", -] - [[package]] name = "getrandom" version = "0.2.8" @@ -833,30 +630,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gif" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "gif" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" -dependencies = [ - "color_quant", - "weezl", ] [[package]] @@ -878,15 +653,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" -dependencies = [ - "crunchy", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -1028,31 +794,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "image" -version = "0.24.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif 0.11.4", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", - "scoped_threadpool", - "tiff", -] - -[[package]] -name = "imagesize" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72ad49b554c1728b1e83254a1b1565aea4161e28dabbfa171fc15fe62299caf" - [[package]] name = "indexmap" version = "1.9.2" @@ -1086,7 +827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1104,7 +845,7 @@ dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1122,15 +863,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" -[[package]] -name = "jpeg-decoder" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" -dependencies = [ - "rayon", -] - [[package]] name = "js-sys" version = "0.3.61" @@ -1140,24 +872,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kurbo" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" -dependencies = [ - "arrayvec 0.7.2", -] - -[[package]] -name = "kurbo" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8c31eaef73f18e0d938785e01ab471ec73e3f90c3389e84335ade689ba953b" -dependencies = [ - "arrayvec 0.7.2", -] - [[package]] name = "lazy-bytes-cast" version = "5.0.1" @@ -1170,12 +884,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - [[package]] name = "libc" version = "0.2.139" @@ -1235,44 +943,6 @@ dependencies = [ "libc", ] -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "mdcat" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d33eab4d729c39b84648fffbdaafdd2d7ef9d3dfc5c3b423de7f329c5766b0a1" -dependencies = [ - "ansi_term", - "anyhow", - "base64", - "clap", - "clap_complete", - "env_proxy", - "gethostname 0.4.1", - "image", - "libc", - "mime", - "mime_guess", - "once_cell", - "pulldown-cmark", - "reqwest", - "resvg", - "shell-words", - "syntect", - "terminal_size", - "tracing", - "tracing-subscriber", - "url", -] - [[package]] name = "memchr" version = "2.5.0" @@ -1312,16 +982,6 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1346,16 +1006,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", -] - -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", + "windows-sys", ] [[package]] @@ -1409,17 +1060,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1474,12 +1114,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - [[package]] name = "os_str_bytes" version = "6.4.1" @@ -1512,7 +1146,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1521,32 +1155,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - -[[package]] -name = "pin-project" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1565,18 +1173,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" -[[package]] -name = "png" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" -dependencies = [ - "bitflags", - "crc32fast", - "flate2", - "miniz_oxide", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1610,17 +1206,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - [[package]] name = "quote" version = "1.0.23" @@ -1630,34 +1215,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "rctree" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" - [[package]] name = "redox_syscall" version = "0.2.16" @@ -1709,15 +1266,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax", -] - [[package]] name = "regex-syntax" version = "0.6.28" @@ -1730,7 +1278,6 @@ version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ - "async-compression", "base64", "bytes", "encoding_rs", @@ -1749,7 +1296,6 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-native-certs", "rustls-pemfile", "serde", "serde_json", @@ -1768,34 +1314,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "resvg" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76888219c0881e22b0ceab06fddcfe83163cd81642bd60c7842387f9c968a72e" -dependencies = [ - "gif 0.12.0", - "jpeg-decoder", - "log", - "pico-args", - "png", - "rgb", - "svgfilters", - "svgtypes 0.10.0", - "tiny-skia", - "usvg", - "usvg-text-layout", -] - -[[package]] -name = "rgb" -version = "0.8.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" -dependencies = [ - "bytemuck", -] - [[package]] name = "ring" version = "0.16.20" @@ -1805,34 +1323,12 @@ dependencies = [ "cc", "libc", "once_cell", - "spin 0.5.2", + "spin", "untrusted", "web-sys", "winapi", ] -[[package]] -name = "rosvgtree" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdc23d1ace03d6b8153c7d16f0708cd80b61ee8e80304954803354e67e40d150" -dependencies = [ - "log", - "roxmltree", - "simplecss", - "siphasher", - "svgtypes 0.9.0", -] - -[[package]] -name = "roxmltree" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f595a457b6b8c6cda66a48503e92ee8d19342f905948f29c383200ec9eb1d8" -dependencies = [ - "xmlparser", -] - [[package]] name = "rustix" version = "0.36.9" @@ -1844,7 +1340,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1859,18 +1355,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustls-native-certs" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - [[package]] name = "rustls-pemfile" version = "1.0.2" @@ -1886,22 +1370,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" -[[package]] -name = "rustybuzz" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162bdf42e261bee271b3957691018634488084ef577dddeb6420a9684cab2a6a" -dependencies = [ - "bitflags", - "bytemuck", - "smallvec", - "ttf-parser", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-general-category", - "unicode-script", -] - [[package]] name = "ryu" version = "1.0.13" @@ -1917,27 +1385,12 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - [[package]] name = "scoped-tls" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" - [[package]] name = "scopeguard" version = "1.1.0" @@ -1960,29 +1413,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.152" @@ -2039,21 +1469,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - [[package]] name = "signal-hook" version = "0.3.15" @@ -2084,27 +1499,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a5df39617d7c8558154693a1bb8157a4aab8179209540cc0b10e5dc24e0b18" - -[[package]] -name = "simplecss" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" -dependencies = [ - "log", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - [[package]] name = "slab" version = "0.4.8" @@ -2164,24 +1558,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" -dependencies = [ - "lock_api", -] - -[[package]] -name = "strict-num" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df65f20698aeed245efdde3628a6b559ea1239bbb871af1b6e3b58c413b2bd1" -dependencies = [ - "float-cmp", -] - [[package]] name = "strip-ansi-escapes" version = "0.1.1" @@ -2216,36 +1592,6 @@ dependencies = [ "syn", ] -[[package]] -name = "svgfilters" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639abcebc15fdc2df179f37d6f5463d660c1c79cd552c12343a4600827a04bce" -dependencies = [ - "float-cmp", - "rgb", -] - -[[package]] -name = "svgtypes" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9ee29c1407a5b18ccfe5f6ac82ac11bab3b14407e09c209a6c1a32098b19734" -dependencies = [ - "kurbo 0.8.3", - "siphasher", -] - -[[package]] -name = "svgtypes" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ffacedcdcf1da6579c907279b4f3c5492fbce99fbbf227f5ed270a589c2765" -dependencies = [ - "kurbo 0.9.1", - "siphasher", -] - [[package]] name = "syn" version = "1.0.109" @@ -2287,16 +1633,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" -dependencies = [ - "rustix", - "windows-sys 0.45.0", -] - [[package]] name = "thiserror" version = "1.0.39" @@ -2317,36 +1653,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "tiff" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - [[package]] name = "time" version = "0.1.45" @@ -2358,31 +1664,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "tiny-skia" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfef3412c6975196fdfac41ef232f910be2bb37b9dd3313a49a1a6bc815a5bdb" -dependencies = [ - "arrayref", - "arrayvec 0.7.2", - "bytemuck", - "cfg-if", - "png", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b5edac058fc98f51c935daea4d805b695b38e2f151241cad125ade2a2ac20d" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -2415,7 +1696,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2480,21 +1761,9 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" version = "0.1.30" @@ -2502,36 +1771,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] @@ -2540,45 +1779,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "ttf-parser" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0609f771ad9c6155384897e1df4d948e692667cc0588548b68eb44d052b27633" - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" -[[package]] -name = "unicode-bidi-mirroring" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694" - -[[package]] -name = "unicode-ccc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" - -[[package]] -name = "unicode-general-category" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" - [[package]] name = "unicode-ident" version = "1.0.8" @@ -2594,24 +1800,12 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-script" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" - [[package]] name = "unicode-segmentation" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-vo" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" - [[package]] name = "unicode-width" version = "0.1.10" @@ -2641,51 +1835,12 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "usvg" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b6bb4e62619d9f68aa2d8a823fea2bff302340a1f2d45c264d5b0be170832e" -dependencies = [ - "base64", - "data-url", - "flate2", - "imagesize", - "kurbo 0.9.1", - "log", - "rctree", - "rosvgtree", - "strict-num", -] - -[[package]] -name = "usvg-text-layout" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195386e01bc35f860db024de275a76e7a31afdf975d18beb6d0e44764118b4db" -dependencies = [ - "fontdb", - "kurbo 0.9.1", - "log", - "rustybuzz", - "unicode-bidi", - "unicode-script", - "unicode-vo", - "usvg", -] - [[package]] name = "utf8parse" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "version_check" version = "0.9.4" @@ -2698,7 +1853,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" dependencies = [ - "arrayvec 0.5.2", + "arrayvec", "utf8parse", "vte_generate_state_changes", ] @@ -2927,12 +2082,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "weezl" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" - [[package]] name = "winapi" version = "0.3.9" @@ -2973,36 +2122,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -3093,7 +2212,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" dependencies = [ - "gethostname 0.2.3", + "gethostname", "nix", "winapi", "winapi-wsapoll", @@ -3123,18 +2242,3 @@ name = "xml-rs" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" - -[[package]] -name = "xmlparser" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" - -[[package]] -name = "zune-inflate" -version = "0.2.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589245df6230839c305984dcc0a8385cc72af1fd223f360ffd5d65efa4216d40" -dependencies = [ - "simd-adler32", -] diff --git a/Cargo.toml b/Cargo.toml index 8300c3f..216e8cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,18 +25,17 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" serde_yaml = "0.9.17" tokio = { version = "1.26.0", features = ["full"] } -mdcat = { version = "1.1.0", default-features = false, features =["static"] } -pulldown-cmark = { version = "0.9.2", default-features = false, features = ['simd'] } crossbeam = "0.8.2" crossterm = "0.26.1" copypasta = "0.8.2" chrono = "0.4.23" atty = "0.2.14" +unicode-width = "0.1.10" [dependencies.syntect] version = "5.0.0" default-features = false -features = ["parsing", "regex-fancy", "default-themes", "default-syntaxes"] +features = ["parsing", "regex-fancy", "default-syntaxes"] [profile.release] lto = true diff --git a/src/main.rs b/src/main.rs index 5cb94f5..8f7b1a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,8 +68,8 @@ fn start_directive(client: ChatGptClient, config: SharedConfig, input: &str) -> let output = client.send_message(input, prompt)?; let output = output.trim(); if config.borrow().highlight && stdout().is_terminal() { - let markdown_render = MarkdownRender::init()?; - markdown_render.print(output)?; + let mut markdown_render = MarkdownRender::new(); + markdown_render.render(output); } else { println!("{output}"); } diff --git a/src/render.rs b/src/render.rs deleted file mode 100644 index 57633a6..0000000 --- a/src/render.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::{repl::ReplyStreamEvent, utils::dump}; -use anyhow::Result; -use crossbeam::channel::Receiver; -use mdcat::{ - push_tty, - terminal::{TerminalProgram, TerminalSize}, - Environment, ResourceAccess, Settings, -}; -use pulldown_cmark::Parser; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; -use syntect::parsing::SyntaxSet; - -pub fn render_stream( - rx: Receiver, - ctrlc: Arc, - markdown_render: Arc, -) -> Result<()> { - let mut buffer = String::new(); - let mut line_index = 0; - loop { - if ctrlc.load(Ordering::SeqCst) { - return Ok(()); - } - if let Ok(evt) = rx.try_recv() { - match evt { - ReplyStreamEvent::Text(text) => { - buffer.push_str(&text); - if text.contains('\n') { - let markdown = markdown_render.render(&buffer)?; - let lines: Vec<&str> = markdown.lines().collect(); - let (_, print_lines) = lines.split_at(line_index); - let mut print_lines = print_lines.to_vec(); - print_lines.pop(); - if !print_lines.is_empty() { - line_index += print_lines.len(); - dump(print_lines.join("\n").to_string(), 1); - } - } - } - ReplyStreamEvent::Done => { - let markdown = markdown_render.render(&buffer)?; - let tail = markdown - .lines() - .skip(line_index) - .collect::>() - .join("\n"); - dump(tail, 2); - break; - } - } - } - } - - Ok(()) -} - -pub struct MarkdownRender { - env: Environment, - settings: Settings, -} - -impl MarkdownRender { - pub fn init() -> Result { - let terminal = TerminalProgram::detect(); - let env = - Environment::for_local_directory(&std::env::current_dir().expect("Working directory"))?; - let settings = Settings { - resource_access: ResourceAccess::LocalOnly, - syntax_set: SyntaxSet::load_defaults_newlines(), - terminal_capabilities: terminal.capabilities(), - terminal_size: TerminalSize::default(), - }; - Ok(Self { env, settings }) - } - - pub fn print(&self, input: &str) -> Result<()> { - let markdown = self.render(input)?; - dump(markdown, 0); - Ok(()) - } - - pub fn render(&self, input: &str) -> Result { - let source = Parser::new(input); - let mut sink = Vec::new(); - push_tty(&self.settings, &self.env, &mut sink, source)?; - Ok(String::from_utf8_lossy(&sink).into()) - } -} diff --git a/src/render/markdown.rs b/src/render/markdown.rs new file mode 100644 index 0000000..fc0bc3e --- /dev/null +++ b/src/render/markdown.rs @@ -0,0 +1,150 @@ +use syntect::highlighting::Theme; +use syntect::parsing::SyntaxSet; +use syntect::util::as_24_bit_terminal_escaped; +use syntect::{easy::HighlightLines, parsing::SyntaxReference}; + +const THEME: &[u8] = include_bytes!("theme.yaml"); + +pub struct MarkdownRender { + syntax_set: SyntaxSet, + theme: Theme, + md_syntax: SyntaxReference, + txt_syntax: SyntaxReference, + code_syntax: SyntaxReference, + line_type: LineType, +} + +impl MarkdownRender { + pub fn new() -> Self { + let syntax_set = SyntaxSet::load_defaults_newlines(); + let theme: Theme = serde_yaml::from_slice(THEME).unwrap(); + let md_syntax = syntax_set.find_syntax_by_extension("md").unwrap().clone(); + let txt_syntax = syntax_set.find_syntax_by_extension("txt").unwrap().clone(); + let code_syntax = txt_syntax.clone(); + let line_type = LineType::Normal; + Self { + syntax_set, + theme, + md_syntax, + code_syntax, + txt_syntax, + line_type, + } + } + + pub fn render(&mut self, src: &str) -> String { + src.split('\n') + .map(|line| self.render_line(line).unwrap_or_else(|| line.to_string())) + .collect::>() + .join("\n") + } + + pub fn render_line(&mut self, line: &str) -> Option { + if let Some(lang) = detect_code_block(line) { + match self.line_type { + LineType::Normal | LineType::CodeEnd => { + self.line_type = LineType::CodeBegin; + self.code_syntax = if lang.is_empty() { + self.txt_syntax.clone() + } else { + self.find_syntax(&lang) + .cloned() + .unwrap_or_else(|| self.txt_syntax.clone()) + }; + } + LineType::CodeBegin | LineType::CodeInner => { + self.line_type = LineType::CodeEnd; + self.code_syntax = self.txt_syntax.clone(); + } + } + self.render_line_inner(line, &self.md_syntax) + } else { + match self.line_type { + LineType::Normal => self.render_line_inner(line, &self.md_syntax), + LineType::CodeEnd => { + self.line_type = LineType::Normal; + self.render_line_inner(line, &self.md_syntax) + } + LineType::CodeBegin => { + self.line_type = LineType::CodeInner; + self.render_line_inner(line, &self.code_syntax) + } + LineType::CodeInner => self.render_line_inner(line, &self.code_syntax), + } + } + } + + pub fn render_line_stateless(&self, line: &str) -> String { + let output = if detect_code_block(line).is_some() { + self.render_line_inner(line, &self.md_syntax) + } else { + match self.line_type { + LineType::Normal | LineType::CodeEnd => { + self.render_line_inner(line, &self.md_syntax) + } + _ => self.render_line_inner(line, &self.code_syntax), + } + }; + + output.unwrap_or_else(|| line.to_string()) + } + + fn render_line_inner(&self, line: &str, syntax: &SyntaxReference) -> Option { + let mut highlighter = HighlightLines::new(syntax, &self.theme); + let ranges = highlighter.highlight_line(line, &self.syntax_set).ok()?; + Some(as_24_bit_terminal_escaped(&ranges[..], false)) + } + + fn find_syntax(&self, lang: &str) -> Option<&SyntaxReference> { + self.syntax_set.find_syntax_by_extension(lang).or_else(|| { + LANGEGUATE_NAME_EXTS + .iter() + .find(|(name, _)| *name == lang.to_lowercase()) + .and_then(|(_, ext)| self.syntax_set.find_syntax_by_extension(ext)) + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum LineType { + Normal, + CodeBegin, + CodeInner, + CodeEnd, +} + +const LANGEGUATE_NAME_EXTS: [(&str, &str); 21] = [ + ("asp", "asa"), + ("actionscript", "as"), + ("c#", "cs"), + ("clojure", "clj"), + ("erlang", "erl"), + ("haskell", "hs"), + ("javascript", "js"), + ("bibtex", "bib"), + ("latex", "tex"), + ("tex", "sty"), + ("ocaml", "ml"), + ("ocamllex", "mll"), + ("ocamlyacc", "mly"), + ("objective-c++", "mm"), + ("objective-c", "m"), + ("pascal", "pas"), + ("perl", "pl"), + ("python", "py"), + ("restructuredtext", "rst"), + ("ruby", "rb"), + ("rust", "rs"), +]; + +fn detect_code_block(line: &str) -> Option { + if !line.starts_with("```") { + return None; + } + let lang = line + .chars() + .skip(3) + .take_while(|v| v.is_alphanumeric()) + .collect(); + Some(lang) +} diff --git a/src/render/mod.rs b/src/render/mod.rs new file mode 100644 index 0000000..d9fcc95 --- /dev/null +++ b/src/render/mod.rs @@ -0,0 +1,120 @@ +mod markdown; + +pub use self::markdown::MarkdownRender; +use crate::repl::ReplyStreamEvent; + +use anyhow::Result; +use crossbeam::channel::Receiver; +use crossterm::{ + cursor, + event::{self, Event, KeyCode, KeyModifiers}, + queue, style, + terminal::{self, disable_raw_mode, enable_raw_mode}, +}; +use std::{ + io::{self, Stdout, Write}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::{Duration, Instant}, +}; +use unicode_width::UnicodeWidthStr; + +pub fn render_stream(rx: Receiver, ctrlc: Arc) -> Result<()> { + enable_raw_mode()?; + let mut stdout = io::stdout(); + queue!(stdout, event::DisableMouseCapture)?; + + let ret = render_stream_inner(rx, ctrlc, &mut stdout); + + queue!(stdout, event::DisableMouseCapture)?; + disable_raw_mode()?; + + ret +} + +pub fn render_stream_inner( + rx: Receiver, + ctrlc: Arc, + writer: &mut Stdout, +) -> Result<()> { + let mut last_tick = Instant::now(); + let tick_rate = Duration::from_millis(200); + let mut buffer = String::new(); + let mut markdown_render = MarkdownRender::new(); + let terminal_columns = terminal::size()?.0; + loop { + if ctrlc.load(Ordering::SeqCst) { + return Ok(()); + } + + if let Ok(evt) = rx.try_recv() { + recover_cursor(writer, terminal_columns, &buffer)?; + + match evt { + ReplyStreamEvent::Text(text) => { + if text.contains('\n') { + let text = format!("{buffer}{text}"); + let mut lines: Vec<&str> = text.split('\n').collect(); + buffer = lines.pop().unwrap_or_default().to_string(); + let output = markdown_render.render(&lines.join("\n")); + queue!( + writer, + style::Print(output), + style::Print("\n"), + style::Print(&buffer), + )?; + } else { + buffer = format!("{buffer}{text}"); + let output = markdown_render.render_line_stateless(&buffer); + queue!(writer, style::Print(&output))?; + } + writer.flush()?; + } + ReplyStreamEvent::Done => { + let output = markdown_render.render_line_stateless(&buffer); + queue!(writer, style::Print(output), style::Print("\n"))?; + writer.flush()?; + break; + } + } + continue; + } + + let timeout = tick_rate + .checked_sub(last_tick.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + if crossterm::event::poll(timeout)? { + if let Event::Key(key) = event::read()? { + match key.code { + KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => { + ctrlc.store(true, Ordering::SeqCst); + return Ok(()); + } + _ => {} + } + } + } + + if last_tick.elapsed() >= tick_rate { + last_tick = Instant::now(); + } + } + Ok(()) +} + +fn recover_cursor(writer: &mut Stdout, terminal_columns: u16, buffer: &str) -> Result<()> { + let buffer_rows = (buffer.width() as u16 + terminal_columns - 1) / terminal_columns; + let (_, row) = cursor::position()?; + if row + 1 >= buffer_rows { + queue!(writer, cursor::MoveTo(0, row + 1 - buffer_rows))?; + } else { + queue!( + writer, + terminal::ScrollUp(buffer_rows - 1 - row), + cursor::MoveTo(0, 0) + )?; + } + Ok(()) +} diff --git a/src/render/theme.yaml b/src/render/theme.yaml new file mode 100644 index 0000000..9475b9b --- /dev/null +++ b/src/render/theme.yaml @@ -0,0 +1,2846 @@ +--- +name: Monokai Extended +author: github.com/jonschlinkert +settings: + foreground: + r: 248 + g: 248 + b: 242 + a: 255 + background: + r: 34 + g: 34 + b: 34 + a: 255 + caret: + r: 248 + g: 248 + b: 240 + a: 255 + line_highlight: + r: 51 + g: 51 + b: 51 + a: 255 + misspelling: ~ + minimap_border: ~ + accent: ~ + popup_css: ~ + phantom_css: ~ + bracket_contents_foreground: + r: 248 + g: 248 + b: 242 + a: 165 + bracket_contents_options: Underline + brackets_foreground: + r: 248 + g: 248 + b: 242 + a: 165 + brackets_background: ~ + brackets_options: Underline + tags_foreground: ~ + tags_options: StippledUnderline + highlight: ~ + find_highlight: + r: 255 + g: 231 + b: 146 + a: 255 + find_highlight_foreground: + r: 0 + g: 0 + b: 0 + a: 255 + gutter: ~ + gutter_foreground: ~ + selection: + r: 68 + g: 68 + b: 68 + a: 255 + selection_foreground: ~ + selection_border: + r: 28 + g: 28 + b: 28 + a: 255 + inactive_selection: ~ + inactive_selection_foreground: ~ + guide: ~ + active_guide: + r: 157 + g: 85 + b: 15 + a: 176 + stack_guide: ~ + shadow: ~ +scopes: + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - comment + excludes: [] + style: + foreground: + r: 117 + g: 113 + b: 94 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string + excludes: [] + style: + foreground: + r: 230 + g: 219 + b: 116 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.numeric + excludes: [] + style: + foreground: + r: 190 + g: 132 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.language + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.preprocessor + excludes: [] + style: + foreground: + r: 190 + g: 132 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.character + excludes: [] + - path: + clear_stack: [] + scopes: + - constant.other + excludes: [] + style: + foreground: + r: 190 + g: 132 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.language + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.other + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.class + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 2 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.other.inherited-class + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 6 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.function + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.parameter + excludes: [] + style: + foreground: + r: 253 + g: 151 + b: 31 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.tag + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.other.attribute-name + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.function + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.constant + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.type + excludes: [] + - path: + clear_stack: [] + scopes: + - support.class + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.other.variable + excludes: [] + style: + foreground: ~ + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string + - constant + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string.regexp + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string + - variable + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.variable + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.tag.sgml.doctype.xml + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.sgml.html + - declaration.doctype + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.sgml.html + - declaration.doctype + - entity + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.sgml.html + - declaration.doctype + - string + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.xml-processing + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.xml-processing + - entity + excludes: [] + - path: + clear_stack: [] + scopes: + - declaration.xml-processing + - string + excludes: [] + - path: + clear_stack: [] + scopes: + - doctype + excludes: [] + style: + foreground: + r: 200 + g: 206 + b: 204 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - comment.block.html + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.tag.script.html + excludes: [] + style: + foreground: ~ + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.other.html + excludes: [] + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.any.html + excludes: [] + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.block.any + excludes: [] + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.inline.any + excludes: [] + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.structure.any.html + excludes: [] + - path: + clear_stack: [] + scopes: + - text.html.basic + - source.js.embedded.html + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.separator.key-value.html + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.basic + - entity.other.attribute-name.html + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.basic + - meta.tag.structure.any.html + - punctuation.definition.string.begin.html + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.begin.html + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.end.html + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.tag.end + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.tag.begin + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.tag + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.parameter.handlebars + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.constant.handlebars + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.function.block.start.handlebars + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.preprocessor.at-rule + - keyword.control.at-rule + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.selector.css + - entity.other.attribute-name.id + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.selector.css + - entity.other.attribute-name.class + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.type.property-name.css + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.constructor.argument.css + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.section.property-list.css + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.tag.css + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.separator.key-value.css + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.terminator.rule.css + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.other.attribute-name.pseudo-element.css + excludes: [] + - path: + clear_stack: [] + scopes: + - entity.other.attribute-name.pseudo-class.css + excludes: [] + - path: + clear_stack: [] + scopes: + - entity.other.attribute-name.pseudo-selector.css + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.less + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.other.less.mixin + excludes: [] + style: + foreground: + r: 224 + g: 253 + b: 206 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.other.attribute-name.pseudo-element.less + excludes: [] + style: + foreground: + r: 255 + g: 145 + b: 23 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.instance.constructor + - meta.function-call.constructor.js + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.template.expression.js + - punctuation.definition.template-expression.begin.js + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.template.expression.js + - punctuation.definition.template-expression.end.js + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.template.expression.js + - punctuation.accessor + excludes: [] + style: + foreground: + r: 175 + g: 241 + b: 50 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.function.js + excludes: [] + - path: + clear_stack: [] + scopes: + - entity.name.function.js + excludes: [] + - path: + clear_stack: [] + scopes: + - support.function.dom.js + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - source.js + - meta.function.js + - punctuation.separator.parameter.function.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.property.object.js + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.operator.accessor.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - source.js + - meta.group.braces.curly + - constant.other.object.key.js + - punctuation.separator.key-value.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - source.js + - meta.group.braces.curly + - constant.other.object.key.js + - string.unquoted.label.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.type.object.module.js + excludes: [] + - path: + clear_stack: [] + scopes: + - source.js + - meta.function.declaration.js + - support.class.js + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.type.object.module.js + - support.type.object.module.js + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type.js + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.basic + - source.js.embedded.html + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type.function.js + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.numeric.js + excludes: [] + style: + foreground: + r: 174 + g: 129 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.language.arguments.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.super.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.this.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.self.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.proto.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.constructor.js + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.prototype.js + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.brace.square.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.brace.round + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.parameters.begin.js + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.parameters.end.js + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.group + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.brace.curly.js + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.object-literal.js + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.mapping.key.json + - string.quoted.double.json + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.separator.sequence.csv + excludes: [] + style: + foreground: + r: 253 + g: 151 + b: 31 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.section.embedded.coffee + excludes: [] + style: + foreground: + r: 230 + g: 159 + b: 102 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.operator.index-start.php + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.operator.index-end.php + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.array.php + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.array.php + - support.function.construct.php + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.array.empty.php + - support.function.construct.php + excludes: [] + style: + foreground: + r: 228 + g: 46 + b: 112 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.function.construct.php + excludes: [] + style: + foreground: + r: 228 + g: 46 + b: 112 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type.function.php + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 221 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.numeric.php + excludes: [] + style: + foreground: + r: 190 + g: 132 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.other.new.php + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.class.php + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.property.php + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.modifier.extends.php + excludes: [] + - path: + clear_stack: [] + scopes: + - storage.type.class.php + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.operator.class.php + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.other.inherited-class.php + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type.php + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.function.php + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.function.construct.php + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.type.class.php + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.function-call.php + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.function-call.static.php + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.function-call.object.php + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.other.phpdoc + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - source.php.embedded.block.html + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - invalid + excludes: [] + - path: + clear_stack: [] + scopes: + - markup.error + excludes: [] + style: + foreground: + r: 248 + g: 248 + b: 240 + a: 255 + background: + r: 249 + g: 38 + b: 114 + a: 255 + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - invalid.deprecated + excludes: [] + - path: + clear_stack: [] + scopes: + - markup.warning + excludes: [] + style: + foreground: + r: 248 + g: 248 + b: 240 + a: 255 + background: + r: 174 + g: 129 + b: 255 + a: 255 + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.diff + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.diff.header + excludes: [] + style: + foreground: + r: 117 + g: 113 + b: 94 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.deleted + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.inserted + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.changed + excludes: [] + style: + foreground: + r: 230 + g: 219 + b: 116 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.diff + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.diff.range + excludes: [] + style: + foreground: + r: 59 + g: 192 + b: 240 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - storage.type.class.python + excludes: [] + - path: + clear_stack: [] + scopes: + - storage.type.function.python + excludes: [] + - path: + clear_stack: [] + scopes: + - storage.modifier.global.python + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.control.import.python + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.control.import.from.python + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 221 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.type.exception.python + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.variable.perl + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.other.readwrite.global.perl + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.other.predefined.perl + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.operator.comparison.perl + excludes: [] + style: + foreground: + r: 228 + g: 46 + b: 112 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.function.perl + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - comment.line.number-sign.perl + excludes: [] + style: + foreground: + r: 117 + g: 113 + b: 94 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.begin.perl + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.end.perl + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.character.escape.perl + excludes: [] + style: + foreground: + r: 220 + g: 50 + b: 47 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.language.ruby + excludes: [] + - path: + clear_stack: [] + scopes: + - constant.numeric.ruby + excludes: [] + style: + foreground: + r: 174 + g: 129 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.variable.ruby + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.function.method.with-arguments.ruby + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.language.ruby + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.function.ruby + excludes: [] + style: + foreground: + r: 246 + g: 170 + b: 17 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.control.ruby + excludes: [] + - path: + clear_stack: [] + scopes: + - keyword.control.def.ruby + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 1 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.control.class.ruby + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.class.ruby + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.type.class.ruby + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.control.ruby + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.class.ruby + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.other.special-method.ruby + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.constant.ruby + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - constant.other.symbol.ruby + excludes: [] + style: + foreground: + r: 246 + g: 240 + b: 128 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.section.embedded.ruby + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.begin.ruby + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.end.ruby + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - keyword.other.special-method.ruby + excludes: [] + style: + foreground: + r: 228 + g: 46 + b: 112 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.markdown + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.markdown + - markup.raw.inline + excludes: [] + style: + foreground: + r: 236 + g: 53 + b: 51 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - text.html.markdown + - meta.dummy.line-break + excludes: [] + style: + foreground: + r: 224 + g: 237 + b: 221 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markdown.heading + excludes: [] + - path: + clear_stack: [] + scopes: + - markup.heading + excludes: [] + - path: + clear_stack: [] + scopes: + - markup.heading + - entity.name + excludes: [] + - path: + clear_stack: [] + scopes: + - markup.heading.markdown + - punctuation.definition.heading.markdown + excludes: [] + style: + foreground: + r: 253 + g: 151 + b: 31 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.italic + excludes: [] + style: + foreground: + r: 228 + g: 46 + b: 112 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.bold + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: + bits: 1 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.underline + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 2 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.strike + excludes: [] + style: + foreground: + r: 204 + g: 66 + b: 115 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.quote + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.blockquote.markdown + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.quote + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string.other.link.title.markdown + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 2 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.raw.block + excludes: [] + style: + foreground: + r: 174 + g: 129 + b: 255 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.list_item.markdown + excludes: [] + style: + foreground: + r: 119 + g: 119 + b: 119 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.raw.block.fenced.markdown + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: + r: 2 + g: 2 + b: 2 + a: 255 + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.fenced.markdown + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.language.fenced.markdown + excludes: [] + style: + foreground: + r: 99 + g: 96 + b: 80 + a: 255 + background: + r: 34 + g: 34 + b: 34 + a: 255 + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.language.fenced.markdown + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.separator + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 51 + background: + r: 255 + g: 255 + b: 255 + a: 15 + font_style: + bits: 1 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.table + excludes: [] + style: + foreground: + r: 180 + g: 42 + b: 29 + a: 255 + background: + r: 255 + g: 58 + b: 40 + a: 26 + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.math.tex + excludes: [] + style: + foreground: + r: 230 + g: 219 + b: 116 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - other.package.exclude + excludes: [] + - path: + clear_stack: [] + scopes: + - other.remove + excludes: [] + style: + foreground: + r: 211 + g: 32 + b: 31 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - support.function.builtin.shell + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.normal.shell + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - source.shell + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.scope.for-in-loop.shell + excludes: [] + - path: + clear_stack: [] + scopes: + - variable.other.loop.shell + excludes: [] + style: + foreground: + r: 253 + g: 151 + b: 31 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.function.shell + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.end.shell + excludes: [] + - path: + clear_stack: [] + scopes: + - punctuation.definition.string.begin.shell + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.scope.case-block.shell + excludes: [] + - path: + clear_stack: [] + scopes: + - meta.scope.case-body.shell + excludes: [] + style: + foreground: + r: 253 + g: 151 + b: 31 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.logical-expression.shell + excludes: [] + style: + foreground: + r: 255 + g: 255 + b: 255 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - comment.line.number-sign.shell + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 4 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - comment.line.number-sign.makefile + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - punctuation.definition.comment.makefile + excludes: [] + style: + foreground: + r: 124 + g: 120 + b: 101 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - variable.other.makefile + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - entity.name.function.makefile + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - meta.function.makefile + excludes: [] + style: + foreground: + r: 102 + g: 217 + b: 239 + a: 255 + background: ~ + font_style: + bits: 0 + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.deleted.git_gutter + excludes: [] + style: + foreground: + r: 249 + g: 38 + b: 114 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.inserted.git_gutter + excludes: [] + style: + foreground: + r: 166 + g: 226 + b: 46 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.changed.git_gutter + excludes: [] + style: + foreground: + r: 252 + g: 149 + b: 30 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.ignored.git_gutter + excludes: [] + style: + foreground: + r: 86 + g: 86 + b: 86 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - markup.untracked.git_gutter + excludes: [] + style: + foreground: + r: 86 + g: 86 + b: 86 + a: 255 + background: ~ + font_style: ~ + - scope: + selectors: + - path: + clear_stack: [] + scopes: + - string.other.path.nginx + excludes: [] + style: + foreground: + r: 252 + g: 149 + b: 30 + a: 255 + background: ~ + font_style: ~ + diff --git a/src/repl/handler.rs b/src/repl/handler.rs index 40ce101..809c202 100644 --- a/src/repl/handler.rs +++ b/src/repl/handler.rs @@ -1,6 +1,6 @@ use crate::client::ChatGptClient; use crate::config::SharedConfig; -use crate::render::{self, MarkdownRender}; +use crate::render::render_stream; use crate::utils::dump; use anyhow::Result; @@ -26,7 +26,6 @@ pub struct ReplCmdHandler { config: SharedConfig, state: RefCell, ctrlc: Arc, - render: Arc, } pub struct ReplCmdHandlerState { @@ -36,7 +35,6 @@ pub struct ReplCmdHandlerState { impl ReplCmdHandler { pub fn init(client: ChatGptClient, config: SharedConfig) -> Result { - let render = Arc::new(MarkdownRender::init()?); let save_file = config.as_ref().borrow().open_message_file()?; let ctrlc = Arc::new(AtomicBool::new(false)); let state = RefCell::new(ReplCmdHandlerState { @@ -48,7 +46,6 @@ impl ReplCmdHandler { config, state, ctrlc, - render, }) } @@ -66,9 +63,8 @@ impl ReplCmdHandler { let (tx, rx) = unbounded(); let ctrlc = self.ctrlc.clone(); let wg = wg.clone(); - let render = self.render.clone(); spawn(move || { - let _ = render::render_stream(rx, ctrlc, render); + let _ = render_stream(rx, ctrlc); drop(wg); }); ReplyStreamHandler::new(Some(tx), self.ctrlc.clone())