Merge pull request #1723 from zed-industries/test-branch

Writing settings
This commit is contained in:
Mikayla Maki 2022-10-11 20:33:03 -07:00 committed by GitHub
commit e24a69b838
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 930 additions and 370 deletions

311
Cargo.lock generated
View file

@ -8,7 +8,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"auto_update", "auto_update",
"editor", "editor",
"futures", "futures 0.3.24",
"gpui", "gpui",
"language", "language",
"project", "project",
@ -183,6 +183,19 @@ dependencies = [
"futures-core", "futures-core",
] ]
[[package]]
name = "async-compat"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b48b4ff0c2026db683dea961cd8ea874737f56cffca86fa84415eaddc51c00d"
dependencies = [
"futures-core",
"futures-io",
"once_cell",
"pin-project-lite 0.2.9",
"tokio",
]
[[package]] [[package]]
name = "async-compression" name = "async-compression"
version = "0.3.14" version = "0.3.14"
@ -265,7 +278,7 @@ name = "async-pipe"
version = "0.1.3" version = "0.1.3"
source = "git+https://github.com/zed-industries/async-pipe-rs?rev=82d00a04211cf4e1236029aa03e6b6ce2a74c553#82d00a04211cf4e1236029aa03e6b6ce2a74c553" source = "git+https://github.com/zed-industries/async-pipe-rs?rev=82d00a04211cf4e1236029aa03e6b6ce2a74c553#82d00a04211cf4e1236029aa03e6b6ce2a74c553"
dependencies = [ dependencies = [
"futures", "futures 0.3.24",
"log", "log",
] ]
@ -338,9 +351,9 @@ dependencies = [
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.56" version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -443,7 +456,7 @@ dependencies = [
"axum-core", "axum-core",
"base64", "base64",
"bitflags", "bitflags",
"bytes", "bytes 1.2.1",
"futures-util", "futures-util",
"headers", "headers",
"http", "http",
@ -475,7 +488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4d047478b986f14a13edad31a009e2e05cb241f9805d0d75e4cba4e129ad4d" checksum = "cf4d047478b986f14a13edad31a009e2e05cb241f9805d0d75e4cba4e129ad4d"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes 1.2.1",
"futures-util", "futures-util",
"http", "http",
"http-body", "http-body",
@ -489,7 +502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "277c75e6c814b061ae4947d02335d9659db9771b9950cca670002ae986372f44" checksum = "277c75e6c814b061ae4947d02335d9659db9771b9950cca670002ae986372f44"
dependencies = [ dependencies = [
"axum", "axum",
"bytes", "bytes 1.2.1",
"futures-util", "futures-util",
"http", "http",
"mime", "mime",
@ -661,6 +674,16 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
dependencies = [
"byteorder",
"iovec",
]
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.2.1" version = "1.2.1"
@ -691,7 +714,7 @@ dependencies = [
"anyhow", "anyhow",
"client", "client",
"collections", "collections",
"futures", "futures 0.3.24",
"gpui", "gpui",
"postage", "postage",
"project", "project",
@ -772,12 +795,12 @@ dependencies = [
"bindgen", "bindgen",
"block", "block",
"byteorder", "byteorder",
"bytes", "bytes 1.2.1",
"cocoa", "cocoa",
"core-foundation", "core-foundation",
"core-graphics", "core-graphics",
"foreign-types", "foreign-types",
"futures", "futures 0.3.24",
"gpui", "gpui",
"hmac 0.12.1", "hmac 0.12.1",
"jwt", "jwt",
@ -960,7 +983,7 @@ dependencies = [
"async-tungstenite", "async-tungstenite",
"collections", "collections",
"db", "db",
"futures", "futures 0.3.24",
"gpui", "gpui",
"image", "image",
"isahc", "isahc",
@ -1045,7 +1068,8 @@ dependencies = [
"editor", "editor",
"env_logger", "env_logger",
"envy", "envy",
"futures", "fs",
"futures 0.3.24",
"git", "git",
"gpui", "gpui",
"hyper", "hyper",
@ -1060,6 +1084,7 @@ dependencies = [
"prometheus", "prometheus",
"rand 0.8.5", "rand 0.8.5",
"reqwest", "reqwest",
"rope",
"rpc", "rpc",
"scrypt", "scrypt",
"serde", "serde",
@ -1092,7 +1117,7 @@ dependencies = [
"clock", "clock",
"collections", "collections",
"editor", "editor",
"futures", "futures 0.3.24",
"fuzzy", "fuzzy",
"gpui", "gpui",
"log", "log",
@ -1551,6 +1576,7 @@ dependencies = [
"language", "language",
"postage", "postage",
"project", "project",
"rope",
"serde_json", "serde_json",
"settings", "settings",
"smallvec", "smallvec",
@ -1689,7 +1715,7 @@ dependencies = [
"context_menu", "context_menu",
"ctor", "ctor",
"env_logger", "env_logger",
"futures", "futures 0.3.24",
"fuzzy", "fuzzy",
"git", "git",
"gpui", "gpui",
@ -1704,6 +1730,7 @@ dependencies = [
"postage", "postage",
"project", "project",
"rand 0.8.5", "rand 0.8.5",
"rope",
"rpc", "rpc",
"serde", "serde",
"settings", "settings",
@ -1984,6 +2011,31 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "fs"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"collections",
"fsevent",
"futures 0.3.24",
"git2",
"gpui",
"lazy_static",
"libc",
"log",
"lsp",
"parking_lot 0.11.2",
"regex",
"rope",
"serde",
"serde_json",
"smol",
"tempfile",
"util",
]
[[package]] [[package]]
name = "fs-set-times" name = "fs-set-times"
version = "0.15.0" version = "0.15.0"
@ -2038,9 +2090,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.21" version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
[[package]]
name = "futures"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -2053,9 +2111,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -2063,15 +2121,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -2091,9 +2149,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
@ -2112,9 +2170,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2123,22 +2181,23 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.21" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
dependencies = [ dependencies = [
"futures 0.1.31",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
@ -2149,6 +2208,7 @@ dependencies = [
"pin-project-lite 0.2.9", "pin-project-lite 0.2.9",
"pin-utils", "pin-utils",
"slab", "slab",
"tokio-io",
] ]
[[package]] [[package]]
@ -2229,11 +2289,12 @@ dependencies = [
"async-trait", "async-trait",
"clock", "clock",
"collections", "collections",
"futures", "futures 0.3.24",
"git2", "git2",
"lazy_static", "lazy_static",
"log", "log",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"rope",
"smol", "smol",
"sum_tree", "sum_tree",
"text", "text",
@ -2281,6 +2342,7 @@ dependencies = [
"gpui", "gpui",
"menu", "menu",
"postage", "postage",
"rope",
"settings", "settings",
"text", "text",
"workspace", "workspace",
@ -2307,9 +2369,10 @@ dependencies = [
"etagere", "etagere",
"font-kit", "font-kit",
"foreign-types", "foreign-types",
"futures", "futures 0.3.24",
"gpui_macros", "gpui_macros",
"image", "image",
"itertools",
"lazy_static", "lazy_static",
"log", "log",
"media", "media",
@ -2355,7 +2418,7 @@ version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"fnv", "fnv",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -2364,7 +2427,7 @@ dependencies = [
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tracing", "tracing",
] ]
@ -2403,7 +2466,7 @@ checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
dependencies = [ dependencies = [
"base64", "base64",
"bitflags", "bitflags",
"bytes", "bytes 1.2.1",
"headers-core", "headers-core",
"http", "http",
"httpdate", "httpdate",
@ -2496,7 +2559,7 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"fnv", "fnv",
"itoa", "itoa",
] ]
@ -2507,7 +2570,7 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"http", "http",
"pin-project-lite 0.2.9", "pin-project-lite 0.2.9",
] ]
@ -2542,7 +2605,7 @@ version = "0.14.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
@ -2578,7 +2641,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"hyper", "hyper",
"native-tls", "native-tls",
"tokio", "tokio",
@ -2868,7 +2931,8 @@ dependencies = [
"collections", "collections",
"ctor", "ctor",
"env_logger", "env_logger",
"futures", "fs",
"futures 0.3.24",
"fuzzy", "fuzzy",
"git", "git",
"gpui", "gpui",
@ -2879,6 +2943,7 @@ dependencies = [
"postage", "postage",
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"rope",
"rpc", "rpc",
"serde", "serde",
"serde_json", "serde_json",
@ -3029,7 +3094,7 @@ dependencies = [
"anyhow", "anyhow",
"core-foundation", "core-foundation",
"core-graphics", "core-graphics",
"futures", "futures 0.3.24",
"media", "media",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"serde", "serde",
@ -3066,7 +3131,7 @@ dependencies = [
"collections", "collections",
"ctor", "ctor",
"env_logger", "env_logger",
"futures", "futures 0.3.24",
"gpui", "gpui",
"log", "log",
"lsp-types", "lsp-types",
@ -3159,7 +3224,7 @@ dependencies = [
"anyhow", "anyhow",
"bindgen", "bindgen",
"block", "block",
"bytes", "bytes 1.2.1",
"core-foundation", "core-foundation",
"foreign-types", "foreign-types",
"metal", "metal",
@ -3519,6 +3584,21 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "nvim-rs"
version = "0.5.0"
source = "git+https://github.com/KillTheMule/nvim-rs?branch=master#d701c2790dcb2579f8f4d7003ba30e2100a7d25b"
dependencies = [
"async-trait",
"futures 0.3.24",
"log",
"parity-tokio-ipc",
"rmp",
"rmpv",
"tokio",
"tokio-util 0.7.4",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -3639,6 +3719,20 @@ dependencies = [
"workspace", "workspace",
] ]
[[package]]
name = "parity-tokio-ipc"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
dependencies = [
"futures 0.3.24",
"libc",
"log",
"rand 0.7.3",
"tokio",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "parking" name = "parking"
version = "2.0.0" version = "2.0.0"
@ -3943,7 +4037,7 @@ checksum = "a63d25391d04a097954b76aba742b6b5b74f213dfe3dbaeeb36e8ddc1c657f0b"
dependencies = [ dependencies = [
"atomic", "atomic",
"crossbeam-queue", "crossbeam-queue",
"futures", "futures 0.3.24",
"log", "log",
"pin-project", "pin-project",
"pollster", "pollster",
@ -4012,15 +4106,15 @@ dependencies = [
"clock", "clock",
"collections", "collections",
"db", "db",
"fs",
"fsevent", "fsevent",
"futures", "futures 0.3.24",
"fuzzy", "fuzzy",
"git", "git",
"gpui", "gpui",
"ignore", "ignore",
"language", "language",
"lazy_static", "lazy_static",
"libc",
"log", "log",
"lsp", "lsp",
"parking_lot 0.11.2", "parking_lot 0.11.2",
@ -4029,6 +4123,7 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"rocksdb", "rocksdb",
"rope",
"rpc", "rpc",
"serde", "serde",
"serde_json", "serde_json",
@ -4051,7 +4146,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"context_menu", "context_menu",
"editor", "editor",
"futures", "futures 0.3.24",
"gpui", "gpui",
"menu", "menu",
"postage", "postage",
@ -4070,7 +4165,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"editor", "editor",
"futures", "futures 0.3.24",
"fuzzy", "fuzzy",
"gpui", "gpui",
"language", "language",
@ -4107,7 +4202,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020" checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"prost-derive 0.8.0", "prost-derive 0.8.0",
] ]
@ -4117,7 +4212,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"prost-derive 0.9.0", "prost-derive 0.9.0",
] ]
@ -4127,7 +4222,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"heck 0.3.3", "heck 0.3.3",
"itertools", "itertools",
"lazy_static", "lazy_static",
@ -4173,7 +4268,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"prost 0.9.0", "prost 0.9.0",
] ]
@ -4436,7 +4531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92"
dependencies = [ dependencies = [
"base64", "base64",
"bytes", "bytes 1.2.1",
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
"futures-util", "futures-util",
@ -4506,6 +4601,27 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "rmp"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmpv"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de8813b3a2f95c5138fe5925bfb8784175d88d6bff059ba8ce090aa891319754"
dependencies = [
"num-traits",
"rmp",
]
[[package]] [[package]]
name = "rocksdb" name = "rocksdb"
version = "0.18.0" version = "0.18.0"
@ -4515,6 +4631,20 @@ dependencies = [
"librocksdb-sys", "librocksdb-sys",
] ]
[[package]]
name = "rope"
version = "0.1.0"
dependencies = [
"arrayvec 0.7.2",
"bromberg_sl2",
"gpui",
"log",
"rand 0.8.5",
"smallvec",
"sum_tree",
"util",
]
[[package]] [[package]]
name = "roxmltree" name = "roxmltree"
version = "0.14.1" version = "0.14.1"
@ -4536,7 +4666,7 @@ dependencies = [
"collections", "collections",
"ctor", "ctor",
"env_logger", "env_logger",
"futures", "futures 0.3.24",
"gpui", "gpui",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"prost 0.8.0", "prost 0.8.0",
@ -5013,14 +5143,21 @@ dependencies = [
"anyhow", "anyhow",
"assets", "assets",
"collections", "collections",
"fs",
"futures 0.3.24",
"gpui", "gpui",
"json_comments", "json_comments",
"postage",
"rope",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
"serde_path_to_error", "serde_path_to_error",
"theme", "theme",
"toml", "toml",
"tree-sitter",
"tree-sitter-json 0.19.0",
"unindent",
"util", "util",
] ]
@ -5290,7 +5427,7 @@ dependencies = [
"base64", "base64",
"bitflags", "bitflags",
"byteorder", "byteorder",
"bytes", "bytes 1.2.1",
"crc", "crc",
"crossbeam-queue", "crossbeam-queue",
"dirs 4.0.0", "dirs 4.0.0",
@ -5543,7 +5680,7 @@ dependencies = [
"context_menu", "context_menu",
"dirs 4.0.0", "dirs 4.0.0",
"editor", "editor",
"futures", "futures 0.3.24",
"gpui", "gpui",
"itertools", "itertools",
"lazy_static", "lazy_static",
@ -5569,13 +5706,12 @@ name = "text"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arrayvec 0.7.2",
"bromberg_sl2",
"clock", "clock",
"collections", "collections",
"ctor", "ctor",
"digest 0.9.0", "digest 0.9.0",
"env_logger", "env_logger",
"fs",
"gpui", "gpui",
"lazy_static", "lazy_static",
"log", "log",
@ -5583,6 +5719,7 @@ dependencies = [
"postage", "postage",
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"rope",
"smallvec", "smallvec",
"sum_tree", "sum_tree",
"util", "util",
@ -5754,16 +5891,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.19.2" version = "1.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
dependencies = [ dependencies = [
"bytes", "autocfg 1.1.0",
"bytes 1.2.1",
"libc", "libc",
"memchr", "memchr",
"mio 0.8.4", "mio 0.8.4",
"num_cpus", "num_cpus",
"once_cell",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"pin-project-lite 0.2.9", "pin-project-lite 0.2.9",
"signal-hook-registry", "signal-hook-registry",
@ -5772,6 +5909,17 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "tokio-io"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
dependencies = [
"bytes 0.4.12",
"futures 0.1.31",
"log",
]
[[package]] [[package]]
name = "tokio-io-timeout" name = "tokio-io-timeout"
version = "1.2.0" version = "1.2.0"
@ -5843,7 +5991,7 @@ version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"log", "log",
@ -5853,12 +6001,13 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.3" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
dependencies = [ dependencies = [
"bytes", "bytes 1.2.1",
"futures-core", "futures-core",
"futures-io",
"futures-sink", "futures-sink",
"pin-project-lite 0.2.9", "pin-project-lite 0.2.9",
"tokio", "tokio",
@ -5883,7 +6032,7 @@ dependencies = [
"async-stream", "async-stream",
"async-trait", "async-trait",
"base64", "base64",
"bytes", "bytes 1.2.1",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2", "h2",
@ -5919,7 +6068,7 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"slab", "slab",
"tokio", "tokio",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@ -5932,7 +6081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"bytes", "bytes 1.2.1",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http", "http",
@ -6211,7 +6360,7 @@ checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1"
dependencies = [ dependencies = [
"base64", "base64",
"byteorder", "byteorder",
"bytes", "bytes 1.2.1",
"http", "http",
"httparse", "httparse",
"log", "log",
@ -6230,7 +6379,7 @@ checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
dependencies = [ dependencies = [
"base64", "base64",
"byteorder", "byteorder",
"bytes", "bytes 1.2.1",
"http", "http",
"httparse", "httparse",
"log", "log",
@ -6406,7 +6555,7 @@ name = "util"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures", "futures 0.3.24",
"git2", "git2",
"lazy_static", "lazy_static",
"log", "log",
@ -6476,6 +6625,8 @@ name = "vim"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"assets", "assets",
"async-compat",
"async-trait",
"collections", "collections",
"command_palette", "command_palette",
"editor", "editor",
@ -6483,11 +6634,17 @@ dependencies = [
"indoc", "indoc",
"itertools", "itertools",
"language", "language",
"lazy_static",
"log", "log",
"nvim-rs",
"parking_lot 0.11.2",
"project", "project",
"rope",
"search", "search",
"serde", "serde",
"serde_json",
"settings", "settings",
"tokio",
"util", "util",
"workspace", "workspace",
] ]
@ -7173,7 +7330,8 @@ dependencies = [
"collections", "collections",
"context_menu", "context_menu",
"drag_and_drop", "drag_and_drop",
"futures", "fs",
"futures 0.3.24",
"gpui", "gpui",
"language", "language",
"log", "log",
@ -7256,8 +7414,9 @@ dependencies = [
"editor", "editor",
"env_logger", "env_logger",
"file_finder", "file_finder",
"fs",
"fsevent", "fsevent",
"futures", "futures 0.3.24",
"fuzzy", "fuzzy",
"go_to_line", "go_to_line",
"gpui", "gpui",

View file

@ -3,6 +3,11 @@ members = ["crates/*"]
default-members = ["crates/zed"] default-members = ["crates/zed"]
resolver = "2" resolver = "2"
[workspace.dependencies]
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] }
rand = { version = "0.8" }
[patch.crates-io] [patch.crates-io]
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "366210ae925d7ea0891bc7a0c738f60c77c04d7b" } tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "366210ae925d7ea0891bc7a0c738f60c77c04d7b" }
async-task = { git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e" } async-task = { git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e" }
@ -21,3 +26,4 @@ split-debuginfo = "unpacked"
[profile.release] [profile.release]
debug = true debug = true

View file

@ -16,7 +16,8 @@ required-features = ["seed-support"]
collections = { path = "../collections" } collections = { path = "../collections" }
rpc = { path = "../rpc" } rpc = { path = "../rpc" }
util = { path = "../util" } util = { path = "../util" }
fs = { path = "../fs" }
rope = { path = "../rope" }
anyhow = "1.0.40" anyhow = "1.0.40"
async-trait = "0.1.50" async-trait = "0.1.50"
async-tungstenite = "0.16" async-tungstenite = "0.16"

View file

@ -15,6 +15,7 @@ use editor::{
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Redo, Rename, ToOffset, self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Redo, Rename, ToOffset,
ToggleCodeActions, Undo, ToggleCodeActions, Undo,
}; };
use fs::{FakeFs, Fs as _, LineEnding};
use futures::{channel::mpsc, Future, StreamExt as _}; use futures::{channel::mpsc, Future, StreamExt as _};
use gpui::{ use gpui::{
executor::{self, Deterministic}, executor::{self, Deterministic},
@ -24,17 +25,16 @@ use gpui::{
}; };
use language::{ use language::{
range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
LanguageConfig, LanguageRegistry, LineEnding, OffsetRangeExt, Point, Rope, LanguageConfig, LanguageRegistry, OffsetRangeExt, Rope,
}; };
use lsp::{self, FakeLanguageServer}; use lsp::{self, FakeLanguageServer};
use parking_lot::Mutex; use parking_lot::Mutex;
use project::{ use project::{
fs::{FakeFs, Fs as _}, search::SearchQuery, worktree::WorktreeHandle, DiagnosticSummary, Project, ProjectPath,
search::SearchQuery, ProjectStore, WorktreeId,
worktree::WorktreeHandle,
DiagnosticSummary, Project, ProjectPath, ProjectStore, WorktreeId,
}; };
use rand::prelude::*; use rand::prelude::*;
use rope::point::Point;
use rpc::PeerId; use rpc::PeerId;
use serde_json::json; use serde_json::json;
use settings::{Formatter, Settings}; use settings::{Formatter, Settings};

View file

@ -15,6 +15,7 @@ editor = { path = "../editor" }
language = { path = "../language" } language = { path = "../language" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
project = { path = "../project" } project = { path = "../project" }
rope = { path = "../rope" }
settings = { path = "../settings" } settings = { path = "../settings" }
theme = { path = "../theme" } theme = { path = "../theme" }
util = { path = "../util" } util = { path = "../util" }

View file

@ -14,10 +14,10 @@ use gpui::{
ViewHandle, WeakViewHandle, ViewHandle, WeakViewHandle,
}; };
use language::{ use language::{
Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Selection, SelectionGoal,
SelectionGoal,
}; };
use project::{DiagnosticSummary, Project, ProjectPath}; use project::{DiagnosticSummary, Project, ProjectPath};
use rope::point::Point;
use serde_json::json; use serde_json::json;
use settings::Settings; use settings::Settings;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -738,7 +738,8 @@ mod tests {
DisplayPoint, DisplayPoint,
}; };
use gpui::TestAppContext; use gpui::TestAppContext;
use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16}; use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity};
use rope::point_utf16::PointUtf16;
use serde_json::json; use serde_json::json;
use unindent::Unindent as _; use unindent::Unindent as _;
use workspace::AppState; use workspace::AppState;

View file

@ -30,6 +30,7 @@ gpui = { path = "../gpui" }
language = { path = "../language" } language = { path = "../language" }
lsp = { path = "../lsp" } lsp = { path = "../lsp" }
project = { path = "../project" } project = { path = "../project" }
rope = { path = "../rope" }
rpc = { path = "../rpc" } rpc = { path = "../rpc" }
settings = { path = "../settings" } settings = { path = "../settings" }
snippet = { path = "../snippet" } snippet = { path = "../snippet" }
@ -48,7 +49,7 @@ ordered-float = "2.1.1"
parking_lot = "0.11" parking_lot = "0.11"
postage = { version = "0.4", features = ["futures-traits"] } postage = { version = "0.4", features = ["futures-traits"] }
rand = { version = "0.8.3", optional = true } rand = { version = "0.8.3", optional = true }
serde = { version = "1.0", features = ["derive", "rc"] } serde = { workspace = true }
smallvec = { version = "1.6", features = ["union"] } smallvec = { version = "1.6", features = ["union"] }
smol = "1.2" smol = "1.2"
tree-sitter-rust = { version = "*", optional = true } tree-sitter-rust = { version = "*", optional = true }

View file

@ -11,7 +11,8 @@ use gpui::{
fonts::{FontId, HighlightStyle}, fonts::{FontId, HighlightStyle},
Entity, ModelContext, ModelHandle, Entity, ModelContext, ModelHandle,
}; };
use language::{OffsetUtf16, Point, Subscription as BufferSubscription}; use language::Subscription as BufferSubscription;
use rope::{offset_utf16::OffsetUtf16, point::Point};
use settings::Settings; use settings::Settings;
use std::{any::TypeId, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc}; use std::{any::TypeId, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc};
use sum_tree::{Bias, TreeMap}; use sum_tree::{Bias, TreeMap};
@ -622,7 +623,7 @@ pub mod tests {
use super::*; use super::*;
use crate::{movement, test::marked_display_snapshot}; use crate::{movement, test::marked_display_snapshot};
use gpui::{color::Color, elements::*, test::observe, MutableAppContext}; use gpui::{color::Color, elements::*, test::observe, MutableAppContext};
use language::{Buffer, Language, LanguageConfig, RandomCharIter, SelectionGoal}; use language::{Buffer, Language, LanguageConfig, SelectionGoal};
use rand::{prelude::*, Rng}; use rand::{prelude::*, Rng};
use smol::stream::StreamExt; use smol::stream::StreamExt;
use std::{env, sync::Arc}; use std::{env, sync::Arc};
@ -666,7 +667,9 @@ pub mod tests {
let buffer = cx.update(|cx| { let buffer = cx.update(|cx| {
if rng.gen() { if rng.gen() {
let len = rng.gen_range(0..10); let len = rng.gen_range(0..10);
let text = RandomCharIter::new(&mut rng).take(len).collect::<String>(); let text = util::RandomCharIter::new(&mut rng)
.take(len)
.collect::<String>();
MultiBuffer::build_simple(&text, cx) MultiBuffer::build_simple(&text, cx)
} else { } else {
MultiBuffer::build_random(&mut rng, cx) MultiBuffer::build_random(&mut rng, cx)

View file

@ -7,6 +7,7 @@ use collections::{Bound, HashMap, HashSet};
use gpui::{ElementBox, RenderContext}; use gpui::{ElementBox, RenderContext};
use language::{BufferSnapshot, Chunk, Patch}; use language::{BufferSnapshot, Chunk, Patch};
use parking_lot::Mutex; use parking_lot::Mutex;
use rope::point::Point;
use std::{ use std::{
cell::RefCell, cell::RefCell,
cmp::{self, Ordering}, cmp::{self, Ordering},
@ -18,7 +19,7 @@ use std::{
}, },
}; };
use sum_tree::{Bias, SumTree}; use sum_tree::{Bias, SumTree};
use text::{Edit, Point}; use text::Edit;
const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize]; const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize];
@ -42,7 +43,7 @@ pub struct BlockSnapshot {
pub struct BlockId(usize); pub struct BlockId(usize);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct BlockPoint(pub super::Point); pub struct BlockPoint(pub Point);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
struct BlockRow(u32); struct BlockRow(u32);
@ -994,7 +995,7 @@ mod tests {
use rand::prelude::*; use rand::prelude::*;
use settings::Settings; use settings::Settings;
use std::env; use std::env;
use text::RandomCharIter; use util::RandomCharIter;
#[gpui::test] #[gpui::test]
fn test_offset_for_row() { fn test_offset_for_row() {

View file

@ -5,8 +5,9 @@ use crate::{
}; };
use collections::BTreeMap; use collections::BTreeMap;
use gpui::fonts::HighlightStyle; use gpui::fonts::HighlightStyle;
use language::{Chunk, Edit, Point, TextSummary}; use language::{Chunk, Edit, TextSummary};
use parking_lot::Mutex; use parking_lot::Mutex;
use rope::point::Point;
use std::{ use std::{
any::TypeId, any::TypeId,
cmp::{self, Ordering}, cmp::{self, Ordering},
@ -18,11 +19,11 @@ use std::{
use sum_tree::{Bias, Cursor, FilterCursor, SumTree}; use sum_tree::{Bias, Cursor, FilterCursor, SumTree};
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct FoldPoint(pub super::Point); pub struct FoldPoint(pub Point);
impl FoldPoint { impl FoldPoint {
pub fn new(row: u32, column: u32) -> Self { pub fn new(row: u32, column: u32) -> Self {
Self(super::Point::new(row, column)) Self(Point::new(row, column))
} }
pub fn row(self) -> u32 { pub fn row(self) -> u32 {
@ -1196,8 +1197,8 @@ mod tests {
use settings::Settings; use settings::Settings;
use std::{cmp::Reverse, env, mem, sync::Arc}; use std::{cmp::Reverse, env, mem, sync::Arc};
use sum_tree::TreeMap; use sum_tree::TreeMap;
use text::RandomCharIter;
use util::test::sample_text; use util::test::sample_text;
use util::RandomCharIter;
use Bias::{Left, Right}; use Bias::{Left, Right};
#[gpui::test] #[gpui::test]

View file

@ -3,11 +3,12 @@ use super::{
TextHighlights, TextHighlights,
}; };
use crate::MultiBufferSnapshot; use crate::MultiBufferSnapshot;
use language::{rope, Chunk}; use language::Chunk;
use parking_lot::Mutex; use parking_lot::Mutex;
use rope;
use rope::point::Point;
use std::{cmp, mem, num::NonZeroU32, ops::Range}; use std::{cmp, mem, num::NonZeroU32, ops::Range};
use sum_tree::Bias; use sum_tree::Bias;
use text::Point;
pub struct TabMap(Mutex<TabSnapshot>); pub struct TabMap(Mutex<TabSnapshot>);
@ -332,11 +333,11 @@ impl TabSnapshot {
} }
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct TabPoint(pub super::Point); pub struct TabPoint(pub Point);
impl TabPoint { impl TabPoint {
pub fn new(row: u32, column: u32) -> Self { pub fn new(row: u32, column: u32) -> Self {
Self(super::Point::new(row, column)) Self(Point::new(row, column))
} }
pub fn zero() -> Self { pub fn zero() -> Self {
@ -352,8 +353,8 @@ impl TabPoint {
} }
} }
impl From<super::Point> for TabPoint { impl From<Point> for TabPoint {
fn from(point: super::Point) -> Self { fn from(point: Point) -> Self {
Self(point) Self(point)
} }
} }
@ -362,7 +363,7 @@ pub type TabEdit = text::Edit<TabPoint>;
#[derive(Clone, Debug, Default, Eq, PartialEq)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct TextSummary { pub struct TextSummary {
pub lines: super::Point, pub lines: Point,
pub first_line_chars: u32, pub first_line_chars: u32,
pub last_line_chars: u32, pub last_line_chars: u32,
pub longest_row: u32, pub longest_row: u32,
@ -485,7 +486,6 @@ mod tests {
use super::*; use super::*;
use crate::{display_map::fold_map::FoldMap, MultiBuffer}; use crate::{display_map::fold_map::FoldMap, MultiBuffer};
use rand::{prelude::StdRng, Rng}; use rand::{prelude::StdRng, Rng};
use text::{RandomCharIter, Rope};
#[test] #[test]
fn test_expand_tabs() { fn test_expand_tabs() {
@ -508,7 +508,9 @@ mod tests {
let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap();
let len = rng.gen_range(0..30); let len = rng.gen_range(0..30);
let buffer = if rng.gen() { let buffer = if rng.gen() {
let text = RandomCharIter::new(&mut rng).take(len).collect::<String>(); let text = util::RandomCharIter::new(&mut rng)
.take(len)
.collect::<String>();
MultiBuffer::build_simple(&text, cx) MultiBuffer::build_simple(&text, cx)
} else { } else {
MultiBuffer::build_random(&mut rng, cx) MultiBuffer::build_random(&mut rng, cx)
@ -522,7 +524,7 @@ mod tests {
log::info!("FoldMap text: {:?}", folds_snapshot.text()); log::info!("FoldMap text: {:?}", folds_snapshot.text());
let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size);
let text = Rope::from(tabs_snapshot.text().as_str()); let text = rope::Rope::from(tabs_snapshot.text().as_str());
log::info!( log::info!(
"TabMap text (tab size: {}): {:?}", "TabMap text (tab size: {}): {:?}",
tab_size, tab_size,

View file

@ -3,13 +3,14 @@ use super::{
tab_map::{self, TabEdit, TabPoint, TabSnapshot}, tab_map::{self, TabEdit, TabPoint, TabSnapshot},
TextHighlights, TextHighlights,
}; };
use crate::{MultiBufferSnapshot, Point}; use crate::MultiBufferSnapshot;
use gpui::{ use gpui::{
fonts::FontId, text_layout::LineWrapper, Entity, ModelContext, ModelHandle, MutableAppContext, fonts::FontId, text_layout::LineWrapper, Entity, ModelContext, ModelHandle, MutableAppContext,
Task, Task,
}; };
use language::Chunk; use language::Chunk;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use rope::point::Point;
use smol::future::yield_now; use smol::future::yield_now;
use std::{cmp, collections::VecDeque, mem, ops::Range, time::Duration}; use std::{cmp, collections::VecDeque, mem, ops::Range, time::Duration};
use sum_tree::{Bias, Cursor, SumTree}; use sum_tree::{Bias, Cursor, SumTree};
@ -52,7 +53,7 @@ struct TransformSummary {
} }
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct WrapPoint(pub super::Point); pub struct WrapPoint(pub Point);
pub struct WrapChunks<'a> { pub struct WrapChunks<'a> {
input_chunks: tab_map::TabChunks<'a>, input_chunks: tab_map::TabChunks<'a>,
@ -959,7 +960,7 @@ impl SumTreeExt for SumTree<Transform> {
impl WrapPoint { impl WrapPoint {
pub fn new(row: u32, column: u32) -> Self { pub fn new(row: u32, column: u32) -> Self {
Self(super::Point::new(row, column)) Self(Point::new(row, column))
} }
pub fn row(self) -> u32 { pub fn row(self) -> u32 {
@ -1029,7 +1030,6 @@ mod tests {
MultiBuffer, MultiBuffer,
}; };
use gpui::test::observe; use gpui::test::observe;
use language::RandomCharIter;
use rand::prelude::*; use rand::prelude::*;
use settings::Settings; use settings::Settings;
use smol::stream::StreamExt; use smol::stream::StreamExt;
@ -1067,7 +1067,9 @@ mod tests {
MultiBuffer::build_random(&mut rng, cx) MultiBuffer::build_random(&mut rng, cx)
} else { } else {
let len = rng.gen_range(0..10); let len = rng.gen_range(0..10);
let text = RandomCharIter::new(&mut rng).take(len).collect::<String>(); let text = util::RandomCharIter::new(&mut rng)
.take(len)
.collect::<String>();
MultiBuffer::build_simple(&text, cx) MultiBuffer::build_simple(&text, cx)
} }
}); });

View file

@ -43,8 +43,8 @@ pub use items::MAX_TAB_TITLE_LEN;
pub use language::{char_kind, CharKind}; pub use language::{char_kind, CharKind};
use language::{ use language::{
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, Diagnostic, AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, Diagnostic,
DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, OffsetUtf16, Point, DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, Selection, SelectionGoal,
Selection, SelectionGoal, TransactionId, TransactionId,
}; };
use link_go_to_definition::{hide_link_definition, LinkGoToDefinitionState}; use link_go_to_definition::{hide_link_definition, LinkGoToDefinitionState};
pub use multi_buffer::{ pub use multi_buffer::{
@ -54,6 +54,7 @@ pub use multi_buffer::{
use multi_buffer::{MultiBufferChunks, ToOffsetUtf16}; use multi_buffer::{MultiBufferChunks, ToOffsetUtf16};
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction}; use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction};
use rope::{offset_utf16::OffsetUtf16, point::Point};
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection}; use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::Settings; use settings::Settings;

View file

@ -15,8 +15,8 @@ use gpui::{
}; };
use language::{FakeLspAdapter, LanguageConfig, LanguageRegistry}; use language::{FakeLspAdapter, LanguageConfig, LanguageRegistry};
use project::FakeFs; use project::FakeFs;
use rope::point::Point;
use settings::EditorSettings; use settings::EditorSettings;
use text::Point;
use util::{ use util::{
assert_set_eq, assert_set_eq,
test::{marked_text_ranges, marked_text_ranges_by, sample_text, TextRangeMarker}, test::{marked_text_ranges, marked_text_ranges_by, sample_text, TextRangeMarker},

View file

@ -35,8 +35,9 @@ use gpui::{
WeakViewHandle, WeakViewHandle,
}; };
use json::json; use json::json;
use language::{Bias, DiagnosticSeverity, OffsetUtf16, Selection}; use language::{Bias, DiagnosticSeverity, Selection};
use project::ProjectPath; use project::ProjectPath;
use rope::offset_utf16::OffsetUtf16;
use settings::{GitGutter, Settings}; use settings::{GitGutter, Settings};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{

View file

@ -11,6 +11,7 @@ use gpui::{
}; };
use language::{Bias, Buffer, File as _, OffsetRangeExt, SelectionGoal}; use language::{Bias, Buffer, File as _, OffsetRangeExt, SelectionGoal};
use project::{File, FormatTrigger, Project, ProjectEntryId, ProjectPath}; use project::{File, FormatTrigger, Project, ProjectEntryId, ProjectPath};
use rope::point::Point;
use rpc::proto::{self, update_view}; use rpc::proto::{self, update_view};
use settings::Settings; use settings::Settings;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -21,7 +22,7 @@ use std::{
ops::Range, ops::Range,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use text::{Point, Selection}; use text::Selection;
use util::TryFutureExt; use util::TryFutureExt;
use workspace::{ use workspace::{
searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle}, searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle},

View file

@ -1,6 +1,7 @@
use rope::point::Point;
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint}; use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
use crate::{char_kind, CharKind, ToPoint}; use crate::{char_kind, CharKind, ToPoint};
use language::Point;
use std::ops::Range; use std::ops::Range;
pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint { pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
@ -336,7 +337,7 @@ pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range<
mod tests { mod tests {
use super::*; use super::*;
use crate::{test::marked_display_snapshot, Buffer, DisplayMap, ExcerptRange, MultiBuffer}; use crate::{test::marked_display_snapshot, Buffer, DisplayMap, ExcerptRange, MultiBuffer};
use language::Point; use rope::point::Point;
use settings::Settings; use settings::Settings;
#[gpui::test] #[gpui::test]

View file

@ -12,6 +12,7 @@ use language::{
DiagnosticEntry, Event, File, IndentSize, Language, OffsetRangeExt, Outline, OutlineItem, DiagnosticEntry, Event, File, IndentSize, Language, OffsetRangeExt, Outline, OutlineItem,
Selection, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, Selection, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId,
}; };
use rope::{offset_utf16::OffsetUtf16, point::Point, point_utf16::PointUtf16, TextDimension};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
borrow::Cow, borrow::Cow,
@ -27,9 +28,8 @@ use std::{
use sum_tree::{Bias, Cursor, SumTree}; use sum_tree::{Bias, Cursor, SumTree};
use text::{ use text::{
locator::Locator, locator::Locator,
rope::TextDimension,
subscription::{Subscription, Topic}, subscription::{Subscription, Topic},
Edit, OffsetUtf16, Point, PointUtf16, TextSummary, Edit, TextSummary,
}; };
use theme::SyntaxTheme; use theme::SyntaxTheme;
use util::post_inc; use util::post_inc;
@ -168,7 +168,7 @@ struct ExcerptChunks<'a> {
} }
struct ExcerptBytes<'a> { struct ExcerptBytes<'a> {
content_bytes: language::rope::Bytes<'a>, content_bytes: rope::Bytes<'a>,
footer_height: usize, footer_height: usize,
} }
@ -1412,7 +1412,7 @@ impl MultiBuffer {
edit_count: usize, edit_count: usize,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) { ) {
use text::RandomCharIter; use util::RandomCharIter;
let snapshot = self.read(cx); let snapshot = self.read(cx);
let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new(); let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
@ -1451,7 +1451,7 @@ impl MultiBuffer {
) { ) {
use rand::prelude::*; use rand::prelude::*;
use std::env; use std::env;
use text::RandomCharIter; use util::RandomCharIter;
let max_excerpts = env::var("MAX_EXCERPTS") let max_excerpts = env::var("MAX_EXCERPTS")
.map(|i| i.parse().expect("invalid `MAX_EXCERPTS` variable")) .map(|i| i.parse().expect("invalid `MAX_EXCERPTS` variable"))
@ -3337,7 +3337,7 @@ mod tests {
use rand::prelude::*; use rand::prelude::*;
use settings::Settings; use settings::Settings;
use std::{env, rc::Rc}; use std::{env, rc::Rc};
use text::{Point, RandomCharIter};
use util::test::sample_text; use util::test::sample_text;
#[gpui::test] #[gpui::test]
@ -3955,7 +3955,9 @@ mod tests {
} }
_ => { _ => {
let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) { let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) {
let base_text = RandomCharIter::new(&mut rng).take(10).collect::<String>(); let base_text = util::RandomCharIter::new(&mut rng)
.take(10)
.collect::<String>();
buffers.push(cx.add_model(|cx| Buffer::new(0, base_text, cx))); buffers.push(cx.add_model(|cx| Buffer::new(0, base_text, cx)));
buffers.last().unwrap() buffers.last().unwrap()
} else { } else {

View file

@ -1,10 +1,10 @@
use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToOffsetUtf16, ToPoint}; use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToOffsetUtf16, ToPoint};
use rope::{offset_utf16::OffsetUtf16, point::Point, TextDimension};
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
ops::{Range, Sub}, ops::{Range, Sub},
}; };
use sum_tree::Bias; use sum_tree::Bias;
use text::{rope::TextDimension, OffsetUtf16, Point};
#[derive(Clone, Eq, PartialEq, Debug, Hash)] #[derive(Clone, Eq, PartialEq, Debug, Hash)]
pub struct Anchor { pub struct Anchor {

View file

@ -8,7 +8,8 @@ use std::{
use collections::HashMap; use collections::HashMap;
use gpui::{AppContext, ModelHandle, MutableAppContext}; use gpui::{AppContext, ModelHandle, MutableAppContext};
use itertools::Itertools; use itertools::Itertools;
use language::{rope::TextDimension, Bias, Point, Selection, SelectionGoal, ToPoint}; use language::{Bias, Selection, SelectionGoal, ToPoint};
use rope::{point::Point, TextDimension};
use util::post_inc; use util::post_inc;
use crate::{ use crate::{

31
crates/fs/Cargo.toml Normal file
View file

@ -0,0 +1,31 @@
[package]
name = "fs"
version = "0.1.0"
edition = "2021"
[lib]
path = "src/fs.rs"
[dependencies]
collections = { path = "../collections" }
gpui = { path = "../gpui" }
lsp = { path = "../lsp" }
rope = { path = "../rope" }
util = { path = "../util" }
anyhow = "1.0.57"
async-trait = "0.1"
futures = "0.3"
tempfile = "3"
fsevent = { path = "../fsevent" }
lazy_static = "1.4.0"
parking_lot = "0.11.1"
smol = "1.2.5"
regex = "1.5"
git2 = { version = "0.15", default-features = false }
serde = { workspace = true }
serde_json = { workspace = true }
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
libc = "0.2"
[features]
test-support = []

View file

@ -1,10 +1,18 @@
pub mod repository;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use fsevent::EventStream; use fsevent::EventStream;
use futures::{future::BoxFuture, Stream, StreamExt}; use futures::{future::BoxFuture, Stream, StreamExt};
use git::repository::{GitRepository, LibGitRepository}; use git2::Repository as LibGitRepository;
use language::LineEnding; use lazy_static::lazy_static;
use parking_lot::Mutex as SyncMutex; use parking_lot::Mutex as SyncMutex;
use regex::Regex;
use repository::GitRepository;
use rope::Rope;
use smol::io::{AsyncReadExt, AsyncWriteExt}; use smol::io::{AsyncReadExt, AsyncWriteExt};
use std::borrow::Cow;
use std::cmp;
use std::io::Write;
use std::sync::Arc; use std::sync::Arc;
use std::{ use std::{
io, io,
@ -13,7 +21,7 @@ use std::{
pin::Pin, pin::Pin,
time::{Duration, SystemTime}, time::{Duration, SystemTime},
}; };
use text::Rope; use tempfile::NamedTempFile;
use util::ResultExt; use util::ResultExt;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
@ -21,10 +29,69 @@ use collections::{btree_map, BTreeMap};
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
use futures::lock::Mutex; use futures::lock::Mutex;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
use git::repository::FakeGitRepositoryState; use repository::FakeGitRepositoryState;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
use std::sync::Weak; use std::sync::Weak;
lazy_static! {
static ref CARRIAGE_RETURNS_REGEX: Regex = Regex::new("\r\n|\r").unwrap();
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LineEnding {
Unix,
Windows,
}
impl Default for LineEnding {
fn default() -> Self {
#[cfg(unix)]
return Self::Unix;
#[cfg(not(unix))]
return Self::CRLF;
}
}
impl LineEnding {
pub fn as_str(&self) -> &'static str {
match self {
LineEnding::Unix => "\n",
LineEnding::Windows => "\r\n",
}
}
pub fn detect(text: &str) -> Self {
let mut max_ix = cmp::min(text.len(), 1000);
while !text.is_char_boundary(max_ix) {
max_ix -= 1;
}
if let Some(ix) = text[..max_ix].find(&['\n']) {
if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
Self::Windows
} else {
Self::Unix
}
} else {
Self::default()
}
}
pub fn normalize(text: &mut String) {
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(text, "\n") {
*text = replaced;
}
}
pub fn normalize_arc(text: Arc<str>) -> Arc<str> {
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") {
replaced.into()
} else {
text
}
}
}
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait Fs: Send + Sync { pub trait Fs: Send + Sync {
async fn create_dir(&self, path: &Path) -> Result<()>; async fn create_dir(&self, path: &Path) -> Result<()>;
@ -35,6 +102,7 @@ pub trait Fs: Send + Sync {
async fn remove_file(&self, path: &Path, options: RemoveOptions) -> Result<()>; async fn remove_file(&self, path: &Path, options: RemoveOptions) -> Result<()>;
async fn open_sync(&self, path: &Path) -> Result<Box<dyn io::Read>>; async fn open_sync(&self, path: &Path) -> Result<Box<dyn io::Read>>;
async fn load(&self, path: &Path) -> Result<String>; async fn load(&self, path: &Path) -> Result<String>;
async fn atomic_write(&self, path: PathBuf, text: String) -> Result<()>;
async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()>; async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()>;
async fn canonicalize(&self, path: &Path) -> Result<PathBuf>; async fn canonicalize(&self, path: &Path) -> Result<PathBuf>;
async fn is_file(&self, path: &Path) -> bool; async fn is_file(&self, path: &Path) -> bool;
@ -86,6 +154,33 @@ pub struct Metadata {
pub is_dir: bool, pub is_dir: bool,
} }
impl From<lsp::CreateFileOptions> for CreateOptions {
fn from(options: lsp::CreateFileOptions) -> Self {
Self {
overwrite: options.overwrite.unwrap_or(false),
ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
}
}
}
impl From<lsp::RenameFileOptions> for RenameOptions {
fn from(options: lsp::RenameFileOptions) -> Self {
Self {
overwrite: options.overwrite.unwrap_or(false),
ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
}
}
}
impl From<lsp::DeleteFileOptions> for RemoveOptions {
fn from(options: lsp::DeleteFileOptions) -> Self {
Self {
recursive: options.recursive.unwrap_or(false),
ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
}
}
}
pub struct RealFs; pub struct RealFs;
#[async_trait::async_trait] #[async_trait::async_trait]
@ -168,6 +263,18 @@ impl Fs for RealFs {
Ok(text) Ok(text)
} }
async fn atomic_write(&self, path: PathBuf, data: String) -> Result<()> {
smol::unblock(move || {
let mut tmp_file = NamedTempFile::new()?;
tmp_file.write_all(data.as_bytes())?;
tmp_file.persist(path)?;
Ok::<(), anyhow::Error>(())
})
.await?;
Ok(())
}
async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()> { async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()> {
let buffer_size = text.summary().len.min(10 * 1024); let buffer_size = text.summary().len.min(10 * 1024);
let file = smol::fs::File::create(path).await?; let file = smol::fs::File::create(path).await?;
@ -285,7 +392,7 @@ enum FakeFsEntry {
inode: u64, inode: u64,
mtime: SystemTime, mtime: SystemTime,
entries: BTreeMap<String, Arc<Mutex<FakeFsEntry>>>, entries: BTreeMap<String, Arc<Mutex<FakeFsEntry>>>,
git_repo_state: Option<Arc<SyncMutex<git::repository::FakeGitRepositoryState>>>, git_repo_state: Option<Arc<SyncMutex<repository::FakeGitRepositoryState>>>,
}, },
Symlink { Symlink {
target: PathBuf, target: PathBuf,
@ -788,6 +895,14 @@ impl Fs for FakeFs {
entry.file_content(&path).cloned() entry.file_content(&path).cloned()
} }
async fn atomic_write(&self, path: PathBuf, data: String) -> Result<()> {
self.simulate_random_delay().await;
let path = normalize_path(path.as_path());
self.insert_file(path, data.to_string()).await;
Ok(())
}
async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()> { async fn save(&self, path: &Path, text: &Rope, line_ending: LineEnding) -> Result<()> {
self.simulate_random_delay().await; self.simulate_random_delay().await;
let path = normalize_path(path); let path = normalize_path(path);
@ -897,7 +1012,7 @@ impl Fs for FakeFs {
Arc::new(SyncMutex::new(FakeGitRepositoryState::default())) Arc::new(SyncMutex::new(FakeGitRepositoryState::default()))
}) })
.clone(); .clone();
Some(git::repository::FakeGitRepository::open(state)) Some(repository::FakeGitRepository::open(state))
} else { } else {
None None
} }

View file

@ -9,7 +9,7 @@ path = "src/git.rs"
[dependencies] [dependencies]
anyhow = "1.0.38" anyhow = "1.0.38"
clock = { path = "../clock" } clock = { path = "../clock" }
git2 = { version = "0.15", default-features = false } rope = { path = "../rope" }
lazy_static = "1.4.0" lazy_static = "1.4.0"
sum_tree = { path = "../sum_tree" } sum_tree = { path = "../sum_tree" }
text = { path = "../text" } text = { path = "../text" }
@ -20,6 +20,7 @@ smol = "1.2"
parking_lot = "0.11.1" parking_lot = "0.11.1"
async-trait = "0.1" async-trait = "0.1"
futures = "0.3" futures = "0.3"
git2 = { version = "0.15", default-features = false }
[dev-dependencies] [dev-dependencies]
unindent = "0.1.7" unindent = "0.1.7"

View file

@ -1,7 +1,8 @@
use std::ops::Range; use std::ops::Range;
use rope::point::Point;
use sum_tree::SumTree; use sum_tree::SumTree;
use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point}; use text::{Anchor, BufferSnapshot, OffsetRangeExt};
pub use git2 as libgit; pub use git2 as libgit;
use libgit::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch}; use libgit::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch};

View file

@ -4,7 +4,6 @@ pub use git2 as libgit;
pub use lazy_static::lazy_static; pub use lazy_static::lazy_static;
pub mod diff; pub mod diff;
pub mod repository;
lazy_static! { lazy_static! {
pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git"); pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git");

View file

@ -13,5 +13,6 @@ gpui = { path = "../gpui" }
menu = { path = "../menu" } menu = { path = "../menu" }
settings = { path = "../settings" } settings = { path = "../settings" }
text = { path = "../text" } text = { path = "../text" }
rope = { path = "../rope" }
workspace = { path = "../workspace" } workspace = { path = "../workspace" }
postage = { version = "0.4", features = ["futures-traits"] } postage = { version = "0.4", features = ["futures-traits"] }

View file

@ -4,8 +4,9 @@ use gpui::{
MutableAppContext, RenderContext, View, ViewContext, ViewHandle, MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
}; };
use menu::{Cancel, Confirm}; use menu::{Cancel, Confirm};
use rope::point::Point;
use settings::Settings; use settings::Settings;
use text::{Bias, Point}; use text::Bias;
use workspace::Workspace; use workspace::Workspace;
actions!(go_to_line, [Toggle]); actions!(go_to_line, [Toggle]);

View file

@ -25,9 +25,11 @@ client = { path = "../client" }
clock = { path = "../clock" } clock = { path = "../clock" }
collections = { path = "../collections" } collections = { path = "../collections" }
fuzzy = { path = "../fuzzy" } fuzzy = { path = "../fuzzy" }
fs = { path = "../fs" }
git = { path = "../git" } git = { path = "../git" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
lsp = { path = "../lsp" } lsp = { path = "../lsp" }
rope = { path = "../rope" }
rpc = { path = "../rpc" } rpc = { path = "../rpc" }
settings = { path = "../settings" } settings = { path = "../settings" }
sum_tree = { path = "../sum_tree" } sum_tree = { path = "../sum_tree" }

View file

@ -13,9 +13,11 @@ use crate::{
}; };
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clock::ReplicaId; use clock::ReplicaId;
use fs::LineEnding;
use futures::FutureExt as _; use futures::FutureExt as _;
use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task}; use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task};
use parking_lot::Mutex; use parking_lot::Mutex;
use rope::point::Point;
use settings::Settings; use settings::Settings;
use similar::{ChangeTag, TextDiff}; use similar::{ChangeTag, TextDiff};
use smol::future::yield_now; use smol::future::yield_now;
@ -38,6 +40,8 @@ use sum_tree::TreeMap;
use text::operation_queue::OperationQueue; use text::operation_queue::OperationQueue;
pub use text::{Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Operation as _, *}; pub use text::{Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Operation as _, *};
use theme::SyntaxTheme; use theme::SyntaxTheme;
#[cfg(any(test, feature = "test-support"))]
use util::RandomCharIter;
use util::TryFutureExt as _; use util::TryFutureExt as _;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
@ -368,7 +372,7 @@ impl Buffer {
file, file,
); );
this.text.set_line_ending(proto::deserialize_line_ending( this.text.set_line_ending(proto::deserialize_line_ending(
proto::LineEnding::from_i32(message.line_ending) rpc::proto::LineEnding::from_i32(message.line_ending)
.ok_or_else(|| anyhow!("missing line_ending"))?, .ok_or_else(|| anyhow!("missing line_ending"))?,
)); ));
Ok(this) Ok(this)
@ -1633,9 +1637,7 @@ impl Buffer {
last_end = Some(range.end); last_end = Some(range.end);
let new_text_len = rng.gen_range(0..10); let new_text_len = rng.gen_range(0..10);
let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng) let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
.take(new_text_len)
.collect();
edits.push((range, new_text)); edits.push((range, new_text));
} }

View file

@ -1,9 +1,11 @@
use super::*; use super::*;
use clock::ReplicaId; use clock::ReplicaId;
use collections::BTreeMap; use collections::BTreeMap;
use fs::LineEnding;
use gpui::{ModelHandle, MutableAppContext}; use gpui::{ModelHandle, MutableAppContext};
use proto::deserialize_operation; use proto::deserialize_operation;
use rand::prelude::*; use rand::prelude::*;
use rope::point::Point;
use settings::Settings; use settings::Settings;
use std::{ use std::{
cell::RefCell, cell::RefCell,
@ -14,7 +16,7 @@ use std::{
}; };
use text::network::Network; use text::network::Network;
use unindent::Unindent as _; use unindent::Unindent as _;
use util::{post_inc, test::marked_text_ranges}; use util::{post_inc, test::marked_text_ranges, RandomCharIter};
#[cfg(test)] #[cfg(test)]
#[ctor::ctor] #[ctor::ctor]

View file

@ -1,12 +1,13 @@
use crate::Diagnostic; use crate::Diagnostic;
use collections::HashMap; use collections::HashMap;
use rope::point_utf16::PointUtf16;
use std::{ use std::{
cmp::{Ordering, Reverse}, cmp::{Ordering, Reverse},
iter, iter,
ops::Range, ops::Range,
}; };
use sum_tree::{self, Bias, SumTree}; use sum_tree::{self, Bias, SumTree};
use text::{Anchor, FromAnchor, PointUtf16, ToOffset}; use text::{Anchor, FromAnchor, ToOffset};
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DiagnosticSet { pub struct DiagnosticSet {

View file

@ -22,6 +22,7 @@ use lazy_static::lazy_static;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use postage::watch; use postage::watch;
use regex::Regex; use regex::Regex;
use rope::point_utf16::PointUtf16;
use serde::{de, Deserialize, Deserializer}; use serde::{de, Deserialize, Deserializer};
use serde_json::Value; use serde_json::Value;
use std::{ use std::{

View file

@ -8,19 +8,19 @@ use rpc::proto;
use std::{ops::Range, sync::Arc}; use std::{ops::Range, sync::Arc};
use text::*; use text::*;
pub use proto::{BufferState, LineEnding, Operation, SelectionSet}; pub use proto::{BufferState, Operation, SelectionSet};
pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding { pub fn deserialize_line_ending(message: proto::LineEnding) -> fs::LineEnding {
match message { match message {
LineEnding::Unix => text::LineEnding::Unix, proto::LineEnding::Unix => fs::LineEnding::Unix,
LineEnding::Windows => text::LineEnding::Windows, proto::LineEnding::Windows => fs::LineEnding::Windows,
} }
} }
pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding { pub fn serialize_line_ending(message: fs::LineEnding) -> proto::LineEnding {
match message { match message {
text::LineEnding::Unix => proto::LineEnding::Unix, fs::LineEnding::Unix => proto::LineEnding::Unix,
text::LineEnding::Windows => proto::LineEnding::Windows, fs::LineEnding::Windows => proto::LineEnding::Windows,
} }
} }

View file

@ -1,6 +1,7 @@
use crate::{Grammar, InjectionConfig, Language, LanguageRegistry}; use crate::{Grammar, InjectionConfig, Language, LanguageRegistry};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
use rope::point::Point;
use std::{ use std::{
borrow::Cow, borrow::Cow,
cell::RefCell, cell::RefCell,
@ -10,7 +11,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use sum_tree::{Bias, SeekTarget, SumTree}; use sum_tree::{Bias, SeekTarget, SumTree};
use text::{rope, Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Rope, ToOffset, ToPoint};
use tree_sitter::{ use tree_sitter::{
Node, Parser, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree, Node, Parser, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree,
}; };
@ -1242,7 +1243,7 @@ mod tests {
use crate::LanguageConfig; use crate::LanguageConfig;
use rand::rngs::StdRng; use rand::rngs::StdRng;
use std::env; use std::env;
use text::{Buffer, Point}; use text::Buffer;
use unindent::Unindent as _; use unindent::Unindent as _;
use util::test::marked_text_ranges; use util::test::marked_text_ranges;

View file

@ -22,12 +22,14 @@ client = { path = "../client" }
clock = { path = "../clock" } clock = { path = "../clock" }
collections = { path = "../collections" } collections = { path = "../collections" }
db = { path = "../db" } db = { path = "../db" }
fs = { path = "../fs" }
fsevent = { path = "../fsevent" } fsevent = { path = "../fsevent" }
fuzzy = { path = "../fuzzy" } fuzzy = { path = "../fuzzy" }
git = { path = "../git" } git = { path = "../git" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
language = { path = "../language" } language = { path = "../language" }
lsp = { path = "../lsp" } lsp = { path = "../lsp" }
rope = { path = "../rope" }
rpc = { path = "../rpc" } rpc = { path = "../rpc" }
settings = { path = "../settings" } settings = { path = "../settings" }
sum_tree = { path = "../sum_tree" } sum_tree = { path = "../sum_tree" }
@ -38,7 +40,6 @@ async-trait = "0.1"
futures = "0.3" futures = "0.3"
ignore = "0.4" ignore = "0.4"
lazy_static = "1.4.0" lazy_static = "1.4.0"
libc = "0.2"
log = { version = "0.4.16", features = ["kv_unstable_serde"] } log = { version = "0.4.16", features = ["kv_unstable_serde"] }
parking_lot = "0.11.1" parking_lot = "0.11.1"
postage = { version = "0.4.1", features = ["futures-traits"] } postage = { version = "0.4.1", features = ["futures-traits"] }
@ -58,6 +59,7 @@ rocksdb = "0.18"
client = { path = "../client", features = ["test-support"] } client = { path = "../client", features = ["test-support"] }
collections = { path = "../collections", features = ["test-support"] } collections = { path = "../collections", features = ["test-support"] }
db = { path = "../db", features = ["test-support"] } db = { path = "../db", features = ["test-support"] }
fs = { path = "../fs", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] } language = { path = "../language", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] } lsp = { path = "../lsp", features = ["test-support"] }

View file

@ -8,10 +8,11 @@ use gpui::{AppContext, AsyncAppContext, ModelHandle};
use language::{ use language::{
point_from_lsp, point_to_lsp, point_from_lsp, point_to_lsp,
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
range_from_lsp, Anchor, Bias, Buffer, CachedLspAdapter, PointUtf16, ToPointUtf16, range_from_lsp, Anchor, Bias, Buffer, CachedLspAdapter, ToPointUtf16,
}; };
use lsp::{DocumentHighlightKind, LanguageServer, ServerCapabilities}; use lsp::{DocumentHighlightKind, LanguageServer, ServerCapabilities};
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
use rope::point_utf16::PointUtf16;
use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc}; use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc};
#[async_trait(?Send)] #[async_trait(?Send)]

View file

@ -1,4 +1,3 @@
pub mod fs;
mod ignore; mod ignore;
mod lsp_command; mod lsp_command;
pub mod search; pub mod search;
@ -25,9 +24,8 @@ use language::{
}, },
range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction, range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction,
CodeLabel, Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, CodeLabel, Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent,
File as _, Language, LanguageRegistry, LanguageServerName, LineEnding, LocalFile, File as _, Language, LanguageRegistry, LanguageServerName, LocalFile, OffsetRangeExt,
OffsetRangeExt, Operation, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Operation, Patch, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
Transaction,
}; };
use lsp::{ use lsp::{
DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer, LanguageString, DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer, LanguageString,
@ -37,6 +35,7 @@ use lsp_command::*;
use parking_lot::Mutex; use parking_lot::Mutex;
use postage::watch; use postage::watch;
use rand::prelude::*; use rand::prelude::*;
use rope::point_utf16::PointUtf16;
use search::SearchQuery; use search::SearchQuery;
use serde::Serialize; use serde::Serialize;
use settings::{FormatOnSave, Formatter, Settings}; use settings::{FormatOnSave, Formatter, Settings};
@ -6019,33 +6018,6 @@ impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
} }
} }
impl From<lsp::CreateFileOptions> for fs::CreateOptions {
fn from(options: lsp::CreateFileOptions) -> Self {
Self {
overwrite: options.overwrite.unwrap_or(false),
ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
}
}
}
impl From<lsp::RenameFileOptions> for fs::RenameOptions {
fn from(options: lsp::RenameFileOptions) -> Self {
Self {
overwrite: options.overwrite.unwrap_or(false),
ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
}
}
}
impl From<lsp::DeleteFileOptions> for fs::RemoveOptions {
fn from(options: lsp::DeleteFileOptions) -> Self {
Self {
recursive: options.recursive.unwrap_or(false),
ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
}
}
}
fn serialize_symbol(symbol: &Symbol) -> proto::Symbol { fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
proto::Symbol { proto::Symbol {
language_server_name: symbol.language_server_name.0.to_string(), language_server_name: symbol.language_server_name.0.to_string(),

View file

@ -1,12 +1,14 @@
use crate::{worktree::WorktreeHandle, Event, *}; use crate::{worktree::WorktreeHandle, Event, *};
use fs::RealFs; use fs::LineEnding;
use fs::{FakeFs, RealFs};
use futures::{future, StreamExt}; use futures::{future, StreamExt};
use gpui::{executor::Deterministic, test::subscribe}; use gpui::{executor::Deterministic, test::subscribe};
use language::{ use language::{
tree_sitter_rust, tree_sitter_typescript, Diagnostic, FakeLspAdapter, LanguageConfig, tree_sitter_rust, tree_sitter_typescript, Diagnostic, FakeLspAdapter, LanguageConfig,
LineEnding, OffsetRangeExt, Point, ToPoint, OffsetRangeExt, ToPoint,
}; };
use lsp::Url; use lsp::Url;
use rope::point::Point;
use serde_json::json; use serde_json::json;
use std::{cell::RefCell, os::unix, rc::Rc, task::Poll}; use std::{cell::RefCell, os::unix, rc::Rc, task::Poll};
use unindent::Unindent as _; use unindent::Unindent as _;

View file

@ -1,14 +1,12 @@
use super::{ use super::{ignore::IgnoreStack, DiagnosticSummary};
fs::{self, Fs},
ignore::IgnoreStack,
DiagnosticSummary,
};
use crate::{copy_recursive, ProjectEntryId, RemoveOptions}; use crate::{copy_recursive, ProjectEntryId, RemoveOptions};
use ::ignore::gitignore::{Gitignore, GitignoreBuilder}; use ::ignore::gitignore::{Gitignore, GitignoreBuilder};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use client::{proto, Client}; use client::{proto, Client};
use clock::ReplicaId; use clock::ReplicaId;
use collections::{HashMap, VecDeque}; use collections::{HashMap, VecDeque};
use fs::LineEnding;
use fs::{repository::GitRepository, Fs};
use futures::{ use futures::{
channel::{ channel::{
mpsc::{self, UnboundedSender}, mpsc::{self, UnboundedSender},
@ -17,7 +15,6 @@ use futures::{
Stream, StreamExt, Stream, StreamExt,
}; };
use fuzzy::CharBag; use fuzzy::CharBag;
use git::repository::GitRepository;
use git::{DOT_GIT, GITIGNORE}; use git::{DOT_GIT, GITIGNORE};
use gpui::{ use gpui::{
executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext,
@ -25,13 +22,14 @@ use gpui::{
}; };
use language::{ use language::{
proto::{deserialize_version, serialize_line_ending, serialize_version}, proto::{deserialize_version, serialize_line_ending, serialize_version},
Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope, Buffer, DiagnosticEntry, Rope,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
use postage::{ use postage::{
prelude::{Sink as _, Stream as _}, prelude::{Sink as _, Stream as _},
watch, watch,
}; };
use rope::point_utf16::PointUtf16;
use smol::channel::{self, Sender}; use smol::channel::{self, Sender};
use std::{ use std::{
@ -2970,11 +2968,10 @@ async fn send_worktree_update(client: &Arc<Client>, update: proto::UpdateWorktre
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::fs::FakeFs;
use anyhow::Result; use anyhow::Result;
use client::test::FakeHttpClient; use client::test::FakeHttpClient;
use fs::RealFs; use fs::repository::FakeGitRepository;
use git::repository::FakeGitRepository; use fs::{FakeFs, RealFs};
use gpui::{executor::Deterministic, TestAppContext}; use gpui::{executor::Deterministic, TestAppContext};
use rand::prelude::*; use rand::prelude::*;
use serde_json::json; use serde_json::json;

20
crates/rope/Cargo.toml Normal file
View file

@ -0,0 +1,20 @@
[package]
name = "rope"
version = "0.1.0"
edition = "2021"
[lib]
path = "src/rope.rs"
[dependencies]
bromberg_sl2 = "0.6"
smallvec = { version = "1.6", features = ["union"] }
sum_tree = { path = "../sum_tree" }
arrayvec = "0.7.1"
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
[dev-dependencies]
rand = "0.8.3"
util = { path = "../util", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }

View file

@ -1,7 +1,12 @@
use super::Point; pub mod offset_utf16;
use crate::{OffsetUtf16, PointUtf16}; pub mod point;
pub mod point_utf16;
use arrayvec::ArrayString; use arrayvec::ArrayString;
use bromberg_sl2::{DigestString, HashMatrix}; use bromberg_sl2::{DigestString, HashMatrix};
use offset_utf16::OffsetUtf16;
use point::Point;
use point_utf16::PointUtf16;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{cmp, fmt, io, mem, ops::Range, str}; use std::{cmp, fmt, io, mem, ops::Range, str};
use sum_tree::{Bias, Dimension, SumTree}; use sum_tree::{Bias, Dimension, SumTree};
@ -1073,9 +1078,9 @@ fn find_split_ix(text: &str) -> usize {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::random_char_iter::RandomCharIter;
use rand::prelude::*; use rand::prelude::*;
use std::{cmp::Ordering, env, io::Read}; use std::{cmp::Ordering, env, io::Read};
use util::RandomCharIter;
use Bias::{Left, Right}; use Bias::{Left, Right};
#[test] #[test]

View file

@ -14,12 +14,23 @@ test-support = []
assets = { path = "../assets" } assets = { path = "../assets" }
collections = { path = "../collections" } collections = { path = "../collections" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
fs = { path = "../fs" }
anyhow = "1.0.38"
futures = "0.3"
theme = { path = "../theme" } theme = { path = "../theme" }
util = { path = "../util" } util = { path = "../util" }
anyhow = "1.0.38" rope = { path = "../rope" }
json_comments = "0.2" json_comments = "0.2"
postage = { version = "0.4.1", features = ["futures-traits"] }
schemars = "0.8" schemars = "0.8"
serde = { version = "1.0", features = ["derive", "rc"] } serde = { workspace = true }
serde_json = { version = "1.0", features = ["preserve_order"] } serde_json = { workspace = true }
serde_path_to_error = "0.1.4" serde_path_to_error = "0.1.4"
toml = "0.5" toml = "0.5"
tree-sitter = "*"
tree-sitter-json = "*"
[dev-dependencies]
unindent = "0.1"
gpui = { path = "../gpui", features = ["test-support"] }
fs = { path = "../fs", features = ["test-support"] }

View file

@ -1,4 +1,5 @@
mod keymap_file; mod keymap_file;
pub mod settings_file;
use anyhow::Result; use anyhow::Result;
use gpui::{ use gpui::{
@ -12,8 +13,9 @@ use schemars::{
}; };
use serde::{de::DeserializeOwned, Deserialize}; use serde::{de::DeserializeOwned, Deserialize};
use serde_json::Value; use serde_json::Value;
use std::{collections::HashMap, num::NonZeroU32, str, sync::Arc}; use std::{collections::HashMap, fmt::Write as _, num::NonZeroU32, str, sync::Arc};
use theme::{Theme, ThemeRegistry}; use theme::{Theme, ThemeRegistry};
use tree_sitter::Query;
use util::ResultExt as _; use util::ResultExt as _;
pub use keymap_file::{keymap_file_json_schema, KeymapFileContent}; pub use keymap_file::{keymap_file_json_schema, KeymapFileContent};
@ -501,6 +503,101 @@ pub fn settings_file_json_schema(
serde_json::to_value(root_schema).unwrap() serde_json::to_value(root_schema).unwrap()
} }
pub fn write_top_level_setting(
mut settings_content: String,
top_level_key: &str,
new_val: &str,
) -> String {
let mut parser = tree_sitter::Parser::new();
parser.set_language(tree_sitter_json::language()).unwrap();
let tree = parser.parse(&settings_content, None).unwrap();
let mut cursor = tree_sitter::QueryCursor::new();
let query = Query::new(
tree_sitter_json::language(),
"
(document
(object
(pair
key: (string) @key
value: (_) @value)))
",
)
.unwrap();
let mut first_key_start = None;
let mut existing_value_range = None;
let matches = cursor.matches(&query, tree.root_node(), settings_content.as_bytes());
for mat in matches {
if mat.captures.len() != 2 {
continue;
}
let key = mat.captures[0];
let value = mat.captures[1];
first_key_start.get_or_insert_with(|| key.node.start_byte());
if let Some(key_text) = settings_content.get(key.node.byte_range()) {
if key_text == format!("\"{top_level_key}\"") {
existing_value_range = Some(value.node.byte_range());
break;
}
}
}
match (first_key_start, existing_value_range) {
(None, None) => {
// No document, create a new object and overwrite
settings_content.clear();
write!(
settings_content,
"{{\n \"{}\": \"{new_val}\"\n}}\n",
top_level_key
)
.unwrap();
}
(_, Some(existing_value_range)) => {
// Existing theme key, overwrite
settings_content.replace_range(existing_value_range, &format!("\"{new_val}\""));
}
(Some(first_key_start), None) => {
// No existing theme key, but other settings. Prepend new theme settings and
// match style of first key
let mut row = 0;
let mut column = 0;
for (ix, char) in settings_content.char_indices() {
if ix == first_key_start {
break;
}
if char == '\n' {
row += 1;
column = 0;
} else {
column += char.len_utf8();
}
}
let content = format!(r#""{top_level_key}": "{new_val}","#);
settings_content.insert_str(first_key_start, &content);
if row > 0 {
settings_content.insert_str(
first_key_start + content.len(),
&format!("\n{:width$}", ' ', width = column),
)
} else {
settings_content.insert_str(first_key_start + content.len(), " ")
}
}
}
settings_content
}
fn merge<T: Copy>(target: &mut T, value: Option<T>) { fn merge<T: Copy>(target: &mut T, value: Option<T>) {
if let Some(value) = value { if let Some(value) = value {
*target = value; *target = value;
@ -512,3 +609,108 @@ pub fn parse_json_with_comments<T: DeserializeOwned>(content: &str) -> Result<T>
json_comments::CommentSettings::c_style().strip_comments(content.as_bytes()), json_comments::CommentSettings::c_style().strip_comments(content.as_bytes()),
)?) )?)
} }
#[cfg(test)]
mod tests {
use crate::write_top_level_setting;
use unindent::Unindent;
#[test]
fn test_write_theme_into_settings_with_theme() {
let settings = r#"
{
"theme": "one-dark"
}
"#
.unindent();
let new_settings = r#"
{
"theme": "summerfruit-light"
}
"#
.unindent();
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
#[test]
fn test_write_theme_into_empty_settings() {
let settings = r#"
{
}
"#
.unindent();
let new_settings = r#"
{
"theme": "summerfruit-light"
}
"#
.unindent();
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
#[test]
fn test_write_theme_into_no_settings() {
let settings = "".to_string();
let new_settings = r#"
{
"theme": "summerfruit-light"
}
"#
.unindent();
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
#[test]
fn test_write_theme_into_single_line_settings_without_theme() {
let settings = r#"{ "a": "", "ok": true }"#.to_string();
let new_settings = r#"{ "theme": "summerfruit-light", "a": "", "ok": true }"#;
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
#[test]
fn test_write_theme_pre_object_whitespace() {
let settings = r#" { "a": "", "ok": true }"#.to_string();
let new_settings = r#" { "theme": "summerfruit-light", "a": "", "ok": true }"#;
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
#[test]
fn test_write_theme_into_multi_line_settings_without_theme() {
let settings = r#"
{
"a": "b"
}
"#
.unindent();
let new_settings = r#"
{
"theme": "summerfruit-light",
"a": "b"
}
"#
.unindent();
let settings_after_theme = write_top_level_setting(settings, "theme", "summerfruit-light");
assert_eq!(settings_after_theme, new_settings)
}
}

View file

@ -1,14 +1,59 @@
use fs::Fs;
use futures::StreamExt; use futures::StreamExt;
use gpui::{executor, MutableAppContext}; use gpui::{executor, MutableAppContext};
use postage::sink::Sink as _; use postage::sink::Sink as _;
use postage::{prelude::Stream, watch}; use postage::{prelude::Stream, watch};
use project::Fs;
use serde::Deserialize; use serde::Deserialize;
use settings::{parse_json_with_comments, KeymapFileContent, Settings, SettingsFileContent};
use std::{path::Path, sync::Arc, time::Duration}; use std::{path::Path, sync::Arc, time::Duration};
use theme::ThemeRegistry; use theme::ThemeRegistry;
use util::ResultExt; use util::ResultExt;
use crate::{
parse_json_with_comments, write_top_level_setting, KeymapFileContent, Settings,
SettingsFileContent,
};
// TODO: Switch SettingsFile to open a worktree and buffer for synchronization
// And instant updates in the Zed editor
#[derive(Clone)]
pub struct SettingsFile {
path: &'static Path,
fs: Arc<dyn Fs>,
}
impl SettingsFile {
pub fn new(path: &'static Path, fs: Arc<dyn Fs>) -> Self {
SettingsFile { path, fs }
}
pub async fn rewrite_settings_file<F>(&self, f: F) -> anyhow::Result<()>
where
F: Fn(String) -> String,
{
let content = self.fs.load(self.path).await?;
let new_settings = f(content);
self.fs
.atomic_write(self.path.to_path_buf(), new_settings)
.await?;
Ok(())
}
}
pub fn write_setting(key: &'static str, val: String, cx: &mut MutableAppContext) {
let settings_file = cx.global::<SettingsFile>().clone();
cx.background()
.spawn(async move {
settings_file
.rewrite_settings_file(|settings| write_top_level_setting(settings, key, &val))
.await
})
.detach_and_log_err(cx);
}
#[derive(Clone)] #[derive(Clone)]
pub struct WatchedJsonFile<T>(pub watch::Receiver<T>); pub struct WatchedJsonFile<T>(pub watch::Receiver<T>);
@ -73,7 +118,7 @@ pub fn watch_settings_file(
pub fn keymap_updated(content: KeymapFileContent, cx: &mut MutableAppContext) { pub fn keymap_updated(content: KeymapFileContent, cx: &mut MutableAppContext) {
cx.clear_bindings(); cx.clear_bindings();
settings::KeymapFileContent::load_defaults(cx); KeymapFileContent::load_defaults(cx);
content.add_to_cx(cx).log_err(); content.add_to_cx(cx).log_err();
} }
@ -101,8 +146,8 @@ pub fn watch_keymap_file(mut file: WatchedJsonFile<KeymapFileContent>, cx: &mut
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use project::FakeFs; use crate::{EditorSettings, SoftWrap};
use settings::{EditorSettings, SoftWrap}; use fs::FakeFs;
#[gpui::test] #[gpui::test]
async fn test_watch_settings_files(cx: &mut gpui::TestAppContext) { async fn test_watch_settings_files(cx: &mut gpui::TestAppContext) {

View file

@ -13,23 +13,24 @@ test-support = ["rand"]
[dependencies] [dependencies]
clock = { path = "../clock" } clock = { path = "../clock" }
collections = { path = "../collections" } collections = { path = "../collections" }
fs = { path = "../fs" }
rope = { path = "../rope" }
sum_tree = { path = "../sum_tree" } sum_tree = { path = "../sum_tree" }
anyhow = "1.0.38" anyhow = "1.0.38"
arrayvec = "0.7.1"
digest = { version = "0.9", features = ["std"] } digest = { version = "0.9", features = ["std"] }
bromberg_sl2 = "0.6"
lazy_static = "1.4" lazy_static = "1.4"
log = { version = "0.4.16", features = ["kv_unstable_serde"] } log = { version = "0.4.16", features = ["kv_unstable_serde"] }
parking_lot = "0.11" parking_lot = "0.11"
postage = { version = "0.4.1", features = ["futures-traits"] } postage = { version = "0.4.1", features = ["futures-traits"] }
rand = { version = "0.8.3", optional = true } rand = { version = "0.8.3", optional = true }
regex = "1.5"
smallvec = { version = "1.6", features = ["union"] } smallvec = { version = "1.6", features = ["union"] }
util = { path = "../util" }
regex = "1.5"
[dev-dependencies] [dev-dependencies]
collections = { path = "../collections", features = ["test-support"] } collections = { path = "../collections", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }
ctor = "0.1" ctor = "0.1"
env_logger = "0.9" env_logger = "0.9"
rand = "0.8.3" rand = "0.8.3"

View file

@ -1,9 +1,10 @@
use super::{Point, ToOffset};
use crate::{rope::TextDimension, BufferSnapshot, PointUtf16, ToPoint, ToPointUtf16};
use anyhow::Result; use anyhow::Result;
use rope::{point::Point, point_utf16::PointUtf16, TextDimension};
use std::{cmp::Ordering, fmt::Debug, ops::Range}; use std::{cmp::Ordering, fmt::Debug, ops::Range};
use sum_tree::Bias; use sum_tree::Bias;
use crate::{BufferSnapshot, ToOffset, ToPoint, ToPointUtf16};
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Default)] #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Default)]
pub struct Anchor { pub struct Anchor {
pub timestamp: clock::Local, pub timestamp: clock::Local,

View file

@ -1,36 +0,0 @@
use rand::prelude::*;
pub struct RandomCharIter<T: Rng>(T);
impl<T: Rng> RandomCharIter<T> {
pub fn new(rng: T) -> Self {
Self(rng)
}
}
impl<T: Rng> Iterator for RandomCharIter<T> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
if std::env::var("SIMPLE_TEXT").map_or(false, |v| !v.is_empty()) {
return if self.0.gen_range(0..100) < 5 {
Some('\n')
} else {
Some(self.0.gen_range(b'a'..b'z' + 1).into())
};
}
match self.0.gen_range(0..100) {
// whitespace
0..=19 => [' ', '\n', '\r', '\t'].choose(&mut self.0).copied(),
// two-byte greek letters
20..=32 => char::from_u32(self.0.gen_range(('α' as u32)..('ω' as u32 + 1))),
// // three-byte characters
33..=45 => ['✋', '✅', '❌', '❎', '⭐'].choose(&mut self.0).copied(),
// // four-byte characters
46..=58 => ['🍐', '🏀', '🍗', '🎉'].choose(&mut self.0).copied(),
// ascii letters
_ => Some(self.0.gen_range(b'a'..b'z' + 1).into()),
}
}
}

View file

@ -1,5 +1,7 @@
use crate::Anchor; use rope::TextDimension;
use crate::{rope::TextDimension, BufferSnapshot};
use crate::{Anchor, BufferSnapshot};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::Range; use std::ops::Range;

View file

@ -2,14 +2,8 @@ mod anchor;
pub mod locator; pub mod locator;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub mod network; pub mod network;
mod offset_utf16;
pub mod operation_queue; pub mod operation_queue;
mod patch; mod patch;
mod point;
mod point_utf16;
#[cfg(any(test, feature = "test-support"))]
pub mod random_char_iter;
pub mod rope;
mod selection; mod selection;
pub mod subscription; pub mod subscription;
#[cfg(test)] #[cfg(test)]
@ -20,22 +14,15 @@ pub use anchor::*;
use anyhow::Result; use anyhow::Result;
use clock::ReplicaId; use clock::ReplicaId;
use collections::{HashMap, HashSet}; use collections::{HashMap, HashSet};
use lazy_static::lazy_static; use fs::LineEnding;
use locator::Locator; use locator::Locator;
pub use offset_utf16::*;
use operation_queue::OperationQueue; use operation_queue::OperationQueue;
pub use patch::Patch; pub use patch::Patch;
pub use point::*;
pub use point_utf16::*;
use postage::{barrier, oneshot, prelude::*}; use postage::{barrier, oneshot, prelude::*};
#[cfg(any(test, feature = "test-support"))] use rope::{offset_utf16::OffsetUtf16, point::Point, point_utf16::PointUtf16, TextDimension};
pub use random_char_iter::*;
use regex::Regex;
use rope::TextDimension;
pub use rope::{Chunks, Rope, TextSummary}; pub use rope::{Chunks, Rope, TextSummary};
pub use selection::*; pub use selection::*;
use std::{ use std::{
borrow::Cow,
cmp::{self, Ordering, Reverse}, cmp::{self, Ordering, Reverse},
future::Future, future::Future,
iter::Iterator, iter::Iterator,
@ -49,9 +36,8 @@ pub use sum_tree::Bias;
use sum_tree::{FilterCursor, SumTree, TreeMap}; use sum_tree::{FilterCursor, SumTree, TreeMap};
use undo_map::UndoMap; use undo_map::UndoMap;
lazy_static! { #[cfg(any(test, feature = "test-support"))]
static ref CARRIAGE_RETURNS_REGEX: Regex = Regex::new("\r\n|\r").unwrap(); use util::RandomCharIter;
}
pub type TransactionId = clock::Local; pub type TransactionId = clock::Local;
@ -96,12 +82,6 @@ pub struct Transaction {
pub start: clock::Global, pub start: clock::Global,
} }
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LineEnding {
Unix,
Windows,
}
impl HistoryEntry { impl HistoryEntry {
pub fn transaction_id(&self) -> TransactionId { pub fn transaction_id(&self) -> TransactionId {
self.transaction.id self.transaction.id
@ -1464,9 +1444,7 @@ impl Buffer {
last_end = Some(range.end); last_end = Some(range.end);
let new_text_len = rng.gen_range(0..10); let new_text_len = rng.gen_range(0..10);
let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng) let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
.take(new_text_len)
.collect();
edits.push((range, new_text.into())); edits.push((range, new_text.into()));
} }
@ -2370,56 +2348,6 @@ impl operation_queue::Operation for Operation {
} }
} }
impl Default for LineEnding {
fn default() -> Self {
#[cfg(unix)]
return Self::Unix;
#[cfg(not(unix))]
return Self::CRLF;
}
}
impl LineEnding {
pub fn as_str(&self) -> &'static str {
match self {
LineEnding::Unix => "\n",
LineEnding::Windows => "\r\n",
}
}
pub fn detect(text: &str) -> Self {
let mut max_ix = cmp::min(text.len(), 1000);
while !text.is_char_boundary(max_ix) {
max_ix -= 1;
}
if let Some(ix) = text[..max_ix].find(&['\n']) {
if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
Self::Windows
} else {
Self::Unix
}
} else {
Self::default()
}
}
pub fn normalize(text: &mut String) {
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(text, "\n") {
*text = replaced;
}
}
fn normalize_arc(text: Arc<str>) -> Arc<str> {
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") {
replaced.into()
} else {
text
}
}
}
pub trait ToOffset { pub trait ToOffset {
fn to_offset(&self, snapshot: &BufferSnapshot) -> usize; fn to_offset(&self, snapshot: &BufferSnapshot) -> usize;
} }

View file

@ -19,3 +19,4 @@ log = { version = "0.4.16", features = ["kv_unstable_serde"] }
parking_lot = "0.11.1" parking_lot = "0.11.1"
postage = { version = "0.4.1", features = ["futures-traits"] } postage = { version = "0.4.1", features = ["futures-traits"] }
smol = "1.2.5" smol = "1.2.5"

View file

@ -107,7 +107,9 @@ impl ThemeSelector {
fn show_selected_theme(&mut self, cx: &mut ViewContext<Self>) { fn show_selected_theme(&mut self, cx: &mut ViewContext<Self>) {
if let Some(mat) = self.matches.get(self.selected_index) { if let Some(mat) = self.matches.get(self.selected_index) {
match self.registry.get(&mat.string) { match self.registry.get(&mat.string) {
Ok(theme) => Self::set_theme(theme, cx), Ok(theme) => {
Self::set_theme(theme, cx);
}
Err(error) => { Err(error) => {
log::error!("error loading theme {}: {}", mat.string, error) log::error!("error loading theme {}: {}", mat.string, error)
} }
@ -151,6 +153,10 @@ impl PickerDelegate for ThemeSelector {
fn confirm(&mut self, cx: &mut ViewContext<Self>) { fn confirm(&mut self, cx: &mut ViewContext<Self>) {
self.selection_completed = true; self.selection_completed = true;
let theme_name = cx.global::<Settings>().theme.meta.name.clone();
settings::settings_file::write_setting("theme", theme_name, cx);
cx.emit(Event::Dismissed); cx.emit(Event::Dismissed);
} }

View file

@ -7,21 +7,20 @@ edition = "2021"
doctest = false doctest = false
[features] [features]
test-support = ["rand", "serde_json", "tempdir", "git2"] test-support = ["serde_json", "tempdir", "git2"]
[dependencies] [dependencies]
anyhow = "1.0.38" anyhow = "1.0.38"
futures = "0.3" futures = "0.3"
log = { version = "0.4.16", features = ["kv_unstable_serde"] } log = { version = "0.4.16", features = ["kv_unstable_serde"] }
lazy_static = "1.4.0" lazy_static = "1.4.0"
rand = { version = "0.8", optional = true } rand = { workspace = true }
tempdir = { version = "0.3.7", optional = true } tempdir = { version = "0.3.7", optional = true }
serde_json = { version = "1.0", features = ["preserve_order"], optional = true } serde_json = { version = "1.0", features = ["preserve_order"], optional = true }
git2 = { version = "0.15", default-features = false, optional = true } git2 = { version = "0.15", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
rand = { version = "0.8" }
tempdir = { version = "0.3.7" } tempdir = { version = "0.3.7" }
serde_json = { version = "1.0", features = ["preserve_order"] } serde_json = { version = "1.0", features = ["preserve_order"] }
git2 = { version = "0.15", default-features = false } git2 = { version = "0.15", default-features = false }

View file

@ -2,6 +2,7 @@
pub mod test; pub mod test;
use futures::Future; use futures::Future;
use rand::{seq::SliceRandom, Rng};
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
ops::AddAssign, ops::AddAssign,
@ -155,6 +156,41 @@ pub fn defer<F: FnOnce()>(f: F) -> impl Drop {
Defer(Some(f)) Defer(Some(f))
} }
pub struct RandomCharIter<T: Rng>(T);
impl<T: Rng> RandomCharIter<T> {
pub fn new(rng: T) -> Self {
Self(rng)
}
}
impl<T: Rng> Iterator for RandomCharIter<T> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
if std::env::var("SIMPLE_TEXT").map_or(false, |v| !v.is_empty()) {
return if self.0.gen_range(0..100) < 5 {
Some('\n')
} else {
Some(self.0.gen_range(b'a'..b'z' + 1).into())
};
}
match self.0.gen_range(0..100) {
// whitespace
0..=19 => [' ', '\n', '\r', '\t'].choose(&mut self.0).copied(),
// two-byte greek letters
20..=32 => char::from_u32(self.0.gen_range(('α' as u32)..('ω' as u32 + 1))),
// // three-byte characters
33..=45 => ['✋', '✅', '❌', '❎', '⭐'].choose(&mut self.0).copied(),
// // four-byte characters
46..=58 => ['🍐', '🏀', '🍗', '🎉'].choose(&mut self.0).copied(),
// ascii letters
_ => Some(self.0.gen_range(b'a'..b'z' + 1).into()),
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -27,6 +27,7 @@ command_palette = { path = "../command_palette" }
editor = { path = "../editor" } editor = { path = "../editor" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
language = { path = "../language" } language = { path = "../language" }
rope = { path = "../rope" }
search = { path = "../search" } search = { path = "../search" }
settings = { path = "../settings" } settings = { path = "../settings" }
workspace = { path = "../workspace" } workspace = { path = "../workspace" }

View file

@ -15,7 +15,8 @@ use editor::{
display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, ClipboardSelection, DisplayPoint, display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, ClipboardSelection, DisplayPoint,
}; };
use gpui::{actions, MutableAppContext, ViewContext}; use gpui::{actions, MutableAppContext, ViewContext};
use language::{AutoindentMode, Point, SelectionGoal}; use language::{AutoindentMode, SelectionGoal};
use rope::point::Point;
use workspace::Workspace; use workspace::Workspace;
use self::{ use self::{

View file

@ -51,7 +51,7 @@ impl<'a> NeovimBackedTestContext<'a> {
pub async fn set_shared_state(&mut self, marked_text: &str) -> ContextHandle { pub async fn set_shared_state(&mut self, marked_text: &str) -> ContextHandle {
let context_handle = self.set_state(marked_text, Mode::Normal); let context_handle = self.set_state(marked_text, Mode::Normal);
let selection = self.editor(|editor, cx| editor.selections.newest::<language::Point>(cx)); let selection = self.editor(|editor, cx| editor.selections.newest::<rope::point::Point>(cx));
let text = self.buffer_text(); let text = self.buffer_text();
self.neovim.set_state(selection, &text).await; self.neovim.set_state(selection, &text).await;

View file

@ -8,7 +8,10 @@ use async_compat::Compat;
use async_trait::async_trait; use async_trait::async_trait;
#[cfg(feature = "neovim")] #[cfg(feature = "neovim")]
use gpui::keymap::Keystroke; use gpui::keymap::Keystroke;
use language::{Point, Selection};
use language::Selection;
use rope::point::Point;
#[cfg(feature = "neovim")] #[cfg(feature = "neovim")]
use lazy_static::lazy_static; use lazy_static::lazy_static;
#[cfg(feature = "neovim")] #[cfg(feature = "neovim")]

View file

@ -12,7 +12,9 @@ test-support = [
"call/test-support", "call/test-support",
"client/test-support", "client/test-support",
"project/test-support", "project/test-support",
"settings/test-support" "settings/test-support",
"gpui/test-support",
"fs/test-support"
] ]
[dependencies] [dependencies]
@ -21,6 +23,7 @@ client = { path = "../client" }
collections = { path = "../collections" } collections = { path = "../collections" }
context_menu = { path = "../context_menu" } context_menu = { path = "../context_menu" }
drag_and_drop = { path = "../drag_and_drop" } drag_and_drop = { path = "../drag_and_drop" }
fs = { path = "../fs" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
language = { path = "../language" } language = { path = "../language" }
menu = { path = "../menu" } menu = { path = "../menu" }
@ -42,4 +45,5 @@ call = { path = "../call", features = ["test-support"] }
client = { path = "../client", features = ["test-support"] } client = { path = "../client", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] } project = { path = "../project", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"] }
fs = { path = "../fs", features = ["test-support"] }

View file

@ -35,16 +35,23 @@ pub fn init(cx: &mut MutableAppContext) {
cx.add_action(Dock::move_dock); cx.add_action(Dock::move_dock);
cx.add_action( cx.add_action(
|workspace: &mut Workspace, _: &AnchorDockRight, cx: &mut ViewContext<Workspace>| { |workspace: &mut Workspace, _: &AnchorDockRight, cx: &mut ViewContext<Workspace>| {
settings::settings_file::write_setting("default_dock_anchor", "right".to_string(), cx);
Dock::move_dock(workspace, &MoveDock(DockAnchor::Right), cx) Dock::move_dock(workspace, &MoveDock(DockAnchor::Right), cx)
}, },
); );
cx.add_action( cx.add_action(
|workspace: &mut Workspace, _: &AnchorDockBottom, cx: &mut ViewContext<Workspace>| { |workspace: &mut Workspace, _: &AnchorDockBottom, cx: &mut ViewContext<Workspace>| {
settings::settings_file::write_setting("default_dock_anchor", "bottom".to_string(), cx);
Dock::move_dock(workspace, &MoveDock(DockAnchor::Bottom), cx) Dock::move_dock(workspace, &MoveDock(DockAnchor::Bottom), cx)
}, },
); );
cx.add_action( cx.add_action(
|workspace: &mut Workspace, _: &ExpandDock, cx: &mut ViewContext<Workspace>| { |workspace: &mut Workspace, _: &ExpandDock, cx: &mut ViewContext<Workspace>| {
settings::settings_file::write_setting(
"default_dock_anchor",
"expanded".to_string(),
cx,
);
Dock::move_dock(workspace, &MoveDock(DockAnchor::Expanded), cx) Dock::move_dock(workspace, &MoveDock(DockAnchor::Expanded), cx)
}, },
); );

View file

@ -17,6 +17,7 @@ use client::{proto, Client, PeerId, TypedEnvelope, UserStore};
use collections::{hash_map, HashMap, HashSet}; use collections::{hash_map, HashMap, HashSet};
use dock::{DefaultItemFactory, Dock, ToggleDockButton}; use dock::{DefaultItemFactory, Dock, ToggleDockButton};
use drag_and_drop::DragAndDrop; use drag_and_drop::DragAndDrop;
use fs::{self, Fs};
use futures::{channel::oneshot, FutureExt, StreamExt}; use futures::{channel::oneshot, FutureExt, StreamExt};
use gpui::{ use gpui::{
actions, actions,
@ -32,7 +33,7 @@ use log::{error, warn};
pub use pane::*; pub use pane::*;
pub use pane_group::*; pub use pane_group::*;
use postage::prelude::Stream; use postage::prelude::Stream;
use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, ProjectStore, Worktree, WorktreeId}; use project::{Project, ProjectEntryId, ProjectPath, ProjectStore, Worktree, WorktreeId};
use searchable::SearchableItemHandle; use searchable::SearchableItemHandle;
use serde::Deserialize; use serde::Deserialize;
use settings::{Autosave, DockAnchor, Settings}; use settings::{Autosave, DockAnchor, Settings};
@ -930,7 +931,7 @@ impl AppState {
let settings = Settings::test(cx); let settings = Settings::test(cx);
cx.set_global(settings); cx.set_global(settings);
let fs = project::FakeFs::new(cx.background().clone()); let fs = fs::FakeFs::new(cx.background().clone());
let languages = Arc::new(LanguageRegistry::test()); let languages = Arc::new(LanguageRegistry::test());
let http_client = client::test::FakeHttpClient::with_404_response(); let http_client = client::test::FakeHttpClient::with_404_response();
let client = Client::new(http_client.clone(), cx); let client = Client::new(http_client.clone(), cx);
@ -2805,8 +2806,9 @@ mod tests {
use crate::sidebar::SidebarItem; use crate::sidebar::SidebarItem;
use super::*; use super::*;
use fs::FakeFs;
use gpui::{executor::Deterministic, ModelHandle, TestAppContext, ViewContext}; use gpui::{executor::Deterministic, ModelHandle, TestAppContext, ViewContext};
use project::{FakeFs, Project, ProjectEntryId}; use project::{Project, ProjectEntryId};
use serde_json::json; use serde_json::json;
pub fn default_item_factory( pub fn default_item_factory(

View file

@ -32,6 +32,7 @@ diagnostics = { path = "../diagnostics" }
editor = { path = "../editor" } editor = { path = "../editor" }
file_finder = { path = "../file_finder" } file_finder = { path = "../file_finder" }
search = { path = "../search" } search = { path = "../search" }
fs = { path = "../fs" }
fsevent = { path = "../fsevent" } fsevent = { path = "../fsevent" }
fuzzy = { path = "../fuzzy" } fuzzy = { path = "../fuzzy" }
go_to_line = { path = "../go_to_line" } go_to_line = { path = "../go_to_line" }

View file

@ -14,7 +14,6 @@ use client::{
http::{self, HttpClient}, http::{self, HttpClient},
UserStore, ZED_SECRET_CLIENT_TOKEN, UserStore, ZED_SECRET_CLIENT_TOKEN,
}; };
use fs::OpenOptions;
use futures::{ use futures::{
channel::{mpsc, oneshot}, channel::{mpsc, oneshot},
FutureExt, SinkExt, StreamExt, FutureExt, SinkExt, StreamExt,
@ -26,20 +25,21 @@ use log::LevelFilter;
use parking_lot::Mutex; use parking_lot::Mutex;
use project::{Fs, ProjectStore}; use project::{Fs, ProjectStore};
use serde_json::json; use serde_json::json;
use settings::{self, KeymapFileContent, Settings, SettingsFileContent, WorkingDirectory}; use settings::{
self, settings_file::SettingsFile, KeymapFileContent, Settings, SettingsFileContent,
WorkingDirectory,
};
use smol::process::Command; use smol::process::Command;
use std::{env, ffi::OsStr, fs, panic, path::PathBuf, sync::Arc, thread, time::Duration}; use std::fs::OpenOptions;
use std::{env, ffi::OsStr, panic, path::PathBuf, sync::Arc, thread, time::Duration};
use terminal::terminal_container_view::{get_working_directory, TerminalContainer}; use terminal::terminal_container_view::{get_working_directory, TerminalContainer};
use fs::RealFs;
use settings::settings_file::{watch_keymap_file, watch_settings_file, WatchedJsonFile};
use theme::ThemeRegistry; use theme::ThemeRegistry;
use util::{ResultExt, TryFutureExt}; use util::{ResultExt, TryFutureExt};
use workspace::{self, AppState, ItemHandle, NewFile, OpenPaths, Workspace}; use workspace::{self, AppState, ItemHandle, NewFile, OpenPaths, Workspace};
use zed::{ use zed::{self, build_window_options, initialize_workspace, languages, menus};
self, build_window_options,
fs::RealFs,
initialize_workspace, languages, menus,
settings_file::{watch_keymap_file, watch_settings_file, WatchedJsonFile},
};
fn main() { fn main() {
let http = http::client(); let http = http::client();
@ -65,6 +65,7 @@ fn main() {
let themes = ThemeRegistry::new(Assets, app.font_cache()); let themes = ThemeRegistry::new(Assets, app.font_cache());
let default_settings = Settings::defaults(Assets, &app.font_cache(), &themes); let default_settings = Settings::defaults(Assets, &app.font_cache(), &themes);
let settings_file = SettingsFile::new(&*zed::paths::SETTINGS, fs.clone());
let config_files = load_config_files(&app, fs.clone()); let config_files = load_config_files(&app, fs.clone());
let login_shell_env_loaded = if stdout_is_a_pty() { let login_shell_env_loaded = if stdout_is_a_pty() {
@ -97,10 +98,11 @@ fn main() {
.spawn(languages::init(languages.clone(), cx.background().clone())); .spawn(languages::init(languages.clone(), cx.background().clone()));
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
let (settings_file, keymap_file) = cx.background().block(config_files).unwrap(); let (settings_file_content, keymap_file) = cx.background().block(config_files).unwrap();
//Setup settings global before binding actions //Setup settings global before binding actions
watch_settings_file(default_settings, settings_file, themes.clone(), cx); cx.set_global(settings_file);
watch_settings_file(default_settings, settings_file_content, themes.clone(), cx);
watch_keymap_file(keymap_file, cx); watch_keymap_file(keymap_file, cx);
context_menu::init(cx); context_menu::init(cx);
@ -200,23 +202,23 @@ fn main() {
} }
fn init_paths() { fn init_paths() {
fs::create_dir_all(&*zed::paths::CONFIG_DIR).expect("could not create config path"); std::fs::create_dir_all(&*zed::paths::CONFIG_DIR).expect("could not create config path");
fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path"); std::fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path");
fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path"); std::fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path");
fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path"); std::fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path");
// Copy setting files from legacy locations. TODO: remove this after a few releases. // Copy setting files from legacy locations. TODO: remove this after a few releases.
thread::spawn(|| { thread::spawn(|| {
if fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok() if std::fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok()
&& fs::metadata(&*zed::paths::SETTINGS).is_err() && std::fs::metadata(&*zed::paths::SETTINGS).is_err()
{ {
fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err(); std::fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err();
} }
if fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok() if std::fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok()
&& fs::metadata(&*zed::paths::KEYMAP).is_err() && std::fs::metadata(&*zed::paths::KEYMAP).is_err()
{ {
fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err(); std::fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err();
} }
}); });
} }
@ -231,9 +233,10 @@ fn init_logger() {
const KIB: u64 = 1024; const KIB: u64 = 1024;
const MIB: u64 = 1024 * KIB; const MIB: u64 = 1024 * KIB;
const MAX_LOG_BYTES: u64 = MIB; const MAX_LOG_BYTES: u64 = MIB;
if fs::metadata(&*zed::paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) if std::fs::metadata(&*zed::paths::LOG)
.map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES)
{ {
let _ = fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG); let _ = std::fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG);
} }
let log_file = OpenOptions::new() let log_file = OpenOptions::new()
@ -289,7 +292,7 @@ fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: A
.body(body.into())?; .body(body.into())?;
let response = http.send(request).await.context("error sending panic")?; let response = http.send(request).await.context("error sending panic")?;
if response.status().is_success() { if response.status().is_success() {
fs::remove_file(child_path) std::fs::remove_file(child_path)
.context("error removing panic after sending it successfully") .context("error removing panic after sending it successfully")
.log_err(); .log_err();
} else { } else {
@ -338,7 +341,7 @@ fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: A
}; };
let panic_filename = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string(); let panic_filename = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string();
fs::write( std::fs::write(
zed::paths::LOGS_DIR.join(format!("zed-{}-{}.panic", app_version, panic_filename)), zed::paths::LOGS_DIR.join(format!("zed-{}-{}.panic", app_version, panic_filename)),
&message, &message,
) )
@ -395,7 +398,7 @@ fn stdout_is_a_pty() -> bool {
fn collect_path_args() -> Vec<PathBuf> { fn collect_path_args() -> Vec<PathBuf> {
env::args() env::args()
.skip(1) .skip(1)
.filter_map(|arg| match fs::canonicalize(arg) { .filter_map(|arg| match std::fs::canonicalize(arg) {
Ok(path) => Some(path), Ok(path) => Some(path),
Err(error) => { Err(error) => {
log::error!("error parsing path argument: {}", error); log::error!("error parsing path argument: {}", error);

View file

@ -2,7 +2,6 @@ mod feedback;
pub mod languages; pub mod languages;
pub mod menus; pub mod menus;
pub mod paths; pub mod paths;
pub mod settings_file;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub mod test; pub mod test;
@ -14,6 +13,7 @@ use collab_ui::CollabTitlebarItem;
use collections::VecDeque; use collections::VecDeque;
pub use editor; pub use editor;
use editor::{Editor, MultiBuffer}; use editor::{Editor, MultiBuffer};
use gpui::{ use gpui::{
actions, actions,
geometry::vector::vec2f, geometry::vector::vec2f,
@ -23,7 +23,7 @@ use gpui::{
}; };
use language::Rope; use language::Rope;
pub use lsp; pub use lsp;
pub use project::{self, fs}; pub use project;
use project_panel::ProjectPanel; use project_panel::ProjectPanel;
use search::{BufferSearchBar, ProjectSearchBar}; use search::{BufferSearchBar, ProjectSearchBar};
use serde::Deserialize; use serde::Deserialize;