Merge branch 'main' of https://github.com/zellij-org/zellij into layout-error

This commit is contained in:
a-kenji 2021-06-14 22:05:25 +02:00
commit 4743b7e7ab
49 changed files with 980 additions and 534 deletions

View file

@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [Unreleased] ## [Unreleased]
## [0.13.0] - 2021-06-04
* Fix crash when padding before widechar (https://github.com/zellij-org/zellij/pull/540) * Fix crash when padding before widechar (https://github.com/zellij-org/zellij/pull/540)
* Do not lag when reading input too fast (https://github.com/zellij-org/zellij/pull/536) * Do not lag when reading input too fast (https://github.com/zellij-org/zellij/pull/536)
* Session name optional in attach command (https://github.com/zellij-org/zellij/pull/542) * Session name optional in attach command (https://github.com/zellij-org/zellij/pull/542)
@ -13,6 +15,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* Add option to start in arbitrary modes (https://github.com/zellij-org/zellij/pull/513) * Add option to start in arbitrary modes (https://github.com/zellij-org/zellij/pull/513)
* Attaching to a session respects the `default_mode` setting of the client (https://github.com/zellij-org/zellij/pull/549) * Attaching to a session respects the `default_mode` setting of the client (https://github.com/zellij-org/zellij/pull/549)
* Add option to specify a color theme in the config (https://github.com/zellij-org/zellij/pull/550) * Add option to specify a color theme in the config (https://github.com/zellij-org/zellij/pull/550)
* Fix config options to not depend on `simplified_ui` (https://github.com/zellij-org/zellij/pull/556)
* Don't rename `unnamed` tabs upon deletion of other tabs (https://github.com/zellij-org/zellij/pull/554)
* Add layout to disable the status bar (https://github.com/zellij-org/zellij/pull/555)
* Significantly improve terminal pane performance (https://github.com/zellij-org/zellij/pull/567)
## [0.12.1] - 2021-05-28 ## [0.12.1] - 2021-05-28
* HOTFIX: fix Zellij not responding to input on certain terminals (https://github.com/zellij-org/zellij/issues/538) * HOTFIX: fix Zellij not responding to input on certain terminals (https://github.com/zellij-org/zellij/issues/538)

View file

@ -3,7 +3,7 @@
Thanks for considering to contribute to Zellij! Thanks for considering to contribute to Zellij!
**First**: if you're unsure or afraid of anything, just ask on our [Discord **First**: if you're unsure or afraid of anything, just ask on our [Discord
server][discord-invite-link] or submit the issue or pull request anyway. You server](https://discord.gg/MHV3n76PDq) or submit the issue or pull request anyway. You
won't be yelled at for giving it your best effort. The worst that can happen is won't be yelled at for giving it your best effort. The worst that can happen is
that you'll be politely asked to change something. We appreciate any sort of that you'll be politely asked to change something. We appreciate any sort of
contributions, and don't want a wall of rules to get in the way of that. contributions, and don't want a wall of rules to get in the way of that.

292
Cargo.lock generated
View file

@ -4,11 +4,11 @@ version = 3
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.14.1" version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
dependencies = [ dependencies = [
"gimli 0.23.0", "gimli 0.24.0",
] ]
[[package]] [[package]]
@ -54,16 +54,16 @@ dependencies = [
[[package]] [[package]]
name = "async-executor" name = "async-executor"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
dependencies = [ dependencies = [
"async-task", "async-task",
"concurrent-queue", "concurrent-queue",
"fastrand", "fastrand",
"futures-lite", "futures-lite",
"once_cell", "once_cell",
"vec-arena", "slab",
] ]
[[package]] [[package]]
@ -84,9 +84,9 @@ dependencies = [
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb9af4888a70ad78ecb5efcb0ba95d66a3cf54a88b62ae81559954c7588c7a2" checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b"
dependencies = [ dependencies = [
"concurrent-queue", "concurrent-queue",
"fastrand", "fastrand",
@ -96,8 +96,8 @@ dependencies = [
"once_cell", "once_cell",
"parking", "parking",
"polling", "polling",
"slab",
"socket2", "socket2",
"vec-arena",
"waker-fn", "waker-fn",
"winapi", "winapi",
] ]
@ -122,17 +122,18 @@ dependencies = [
[[package]] [[package]]
name = "async-process" name = "async-process"
version = "1.0.2" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef37b86e2fa961bae5a4d212708ea0154f904ce31d1a4a7f47e1bbc33a0c040b" checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac"
dependencies = [ dependencies = [
"async-io", "async-io",
"blocking", "blocking",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"event-listener", "event-listener",
"futures-lite", "futures-lite",
"libc",
"once_cell", "once_cell",
"signal-hook 0.3.8", "signal-hook 0.3.9",
"winapi", "winapi",
] ]
@ -206,15 +207,16 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.56" version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"miniz_oxide", "miniz_oxide",
"object 0.23.0", "object 0.25.2",
"rustc-demangle", "rustc-demangle",
] ]
@ -255,9 +257,9 @@ checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.6.1" version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -272,10 +274,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
[[package]] [[package]]
name = "cc" name = "cassowary"
version = "1.0.67" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cc"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -419,9 +427,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam" name = "crossbeam"
version = "0.8.0" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80" checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"crossbeam-channel", "crossbeam-channel",
@ -454,9 +462,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.3" version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"crossbeam-utils", "crossbeam-utils",
@ -467,9 +475,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756" checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"crossbeam-utils", "crossbeam-utils",
@ -477,11 +485,10 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.3" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [ dependencies = [
"autocfg",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"lazy_static", "lazy_static",
] ]
@ -533,9 +540,9 @@ dependencies = [
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.12.3" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d6ddad5866bb2170686ed03f6839d31a76e5407d80b1c334a2c24618543ffa" checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"darling_macro", "darling_macro",
@ -543,9 +550,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.12.3" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9ced1fd13dc386d5a8315899de465708cf34ee2a6d9394654515214e67bb846" checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
@ -557,9 +564,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.12.3" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a7a1445d54b2f9792e3b31a3e715feabbace393f38dc4ffd49d94ee9bc487d5" checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
@ -628,9 +635,9 @@ dependencies = [
[[package]] [[package]]
name = "erased-serde" name = "erased-serde"
version = "0.3.13" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0465971a8cc1fa2455c8465aaa377131e1f1cf4983280f474a13e68793aa770c" checksum = "e5b36e6f2295f393f44894c6031f67df4d185b984cd54d08f768ce678007efcd"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -649,9 +656,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
dependencies = [ dependencies = [
"instant", "instant",
] ]
@ -670,9 +677,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -685,9 +692,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -695,15 +702,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -712,15 +719,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
version = "1.11.3" version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"futures-core", "futures-core",
@ -733,10 +740,11 @@ dependencies = [
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
dependencies = [ dependencies = [
"autocfg",
"proc-macro-hack", "proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -745,22 +753,23 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
dependencies = [ dependencies = [
"autocfg",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
@ -796,9 +805,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
@ -829,9 +838,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.23.0" version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
[[package]] [[package]]
name = "gloo-timers" name = "gloo-timers"
@ -854,9 +863,9 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
@ -964,9 +973,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.50" version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@ -994,9 +1003,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.93" version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -1044,24 +1053,24 @@ dependencies = [
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.3.4" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]] [[package]]
name = "memmap2" name = "memmap2"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "397d1a6d6d0563c0f5462bbdae662cf6c784edf5e828e40c7257f85d82bf56dd" checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.6.3" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@ -1162,9 +1171,12 @@ dependencies = [
[[package]] [[package]]
name = "object" name = "object"
version = "0.23.0" version = "0.25.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
@ -1282,9 +1294,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.26" version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -1378,9 +1390,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.5.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"crossbeam-deque", "crossbeam-deque",
@ -1390,9 +1402,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.9.0" version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"crossbeam-deque", "crossbeam-deque",
@ -1412,9 +1424,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.6" 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 = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041" checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@ -1472,9 +1484,9 @@ dependencies = [
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.18" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
@ -1496,9 +1508,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.125" version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -1514,9 +1526,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.125" version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1559,9 +1571,9 @@ dependencies = [
[[package]] [[package]]
name = "signal-hook" name = "signal-hook"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39"
dependencies = [ dependencies = [
"libc", "libc",
"signal-hook-registry", "signal-hook-registry",
@ -1569,9 +1581,9 @@ dependencies = [
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.3.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -1584,9 +1596,9 @@ checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.2" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
@ -1703,9 +1715,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.69" version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1744,9 +1756,9 @@ dependencies = [
[[package]] [[package]]
name = "termbg" name = "termbg"
version = "0.2.3" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e7fa67e879d2b5c902517367809bfab4e69ee6cabc03909141003721bd64282" checksum = "dde5fb83dfdf1491b3615ff3b5fa92c54132d2a67bf24f2a812b3d88d39b55e9"
dependencies = [ dependencies = [
"crossterm", "crossterm",
"thiserror", "thiserror",
@ -1755,9 +1767,9 @@ dependencies = [
[[package]] [[package]]
name = "terminal_size" name = "terminal_size"
version = "0.1.16" version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [ dependencies = [
"libc", "libc",
"winapi", "winapi",
@ -1786,18 +1798,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.24" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.24" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1816,9 +1828,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.25" version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"log", "log",
@ -1840,9 +1852,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.17" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
] ]
@ -1885,9 +1897,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
@ -1909,19 +1921,14 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]] [[package]]
name = "value-bag" name = "value-bag"
version = "1.0.0-alpha.6" version = "1.0.0-alpha.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b676010e055c99033117c2343b33a40a30b91fecd6c49055ac9cd2d6c305ab1" checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae"
dependencies = [ dependencies = [
"ctor", "ctor",
"version_check",
] ]
[[package]]
name = "vec-arena"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34b2f665b594b07095e3ac3f718e13c2197143416fae4c5706cffb7b1af8d7f1"
[[package]] [[package]]
name = "vec_map" name = "vec_map"
version = "0.8.2" version = "0.8.2"
@ -1978,9 +1985,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -1988,9 +1995,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static", "lazy_static",
@ -2003,9 +2010,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.23" version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea" checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"js-sys", "js-sys",
@ -2015,9 +2022,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -2025,9 +2032,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2038,9 +2045,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
[[package]] [[package]]
name = "wasmer" name = "wasmer"
@ -2262,9 +2269,9 @@ dependencies = [
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.50" version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@ -2322,7 +2329,7 @@ dependencies = [
[[package]] [[package]]
name = "zellij" name = "zellij"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"insta", "insta",
"names", "names",
@ -2333,7 +2340,7 @@ dependencies = [
[[package]] [[package]]
name = "zellij-client" name = "zellij-client"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"termbg", "termbg",
"zellij-utils", "zellij-utils",
@ -2341,10 +2348,11 @@ dependencies = [
[[package]] [[package]]
name = "zellij-server" name = "zellij-server"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"ansi_term 0.12.1", "ansi_term 0.12.1",
"async-trait", "async-trait",
"cassowary",
"daemonize", "daemonize",
"insta", "insta",
"serde_json", "serde_json",
@ -2356,7 +2364,7 @@ dependencies = [
[[package]] [[package]]
name = "zellij-tile" name = "zellij-tile"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
@ -2366,14 +2374,14 @@ dependencies = [
[[package]] [[package]]
name = "zellij-tile-utils" name = "zellij-tile-utils"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"ansi_term 0.12.1", "ansi_term 0.12.1",
] ]
[[package]] [[package]]
name = "zellij-utils" name = "zellij-utils"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"async-std", "async-std",
"backtrace", "backtrace",
@ -2388,7 +2396,7 @@ dependencies = [
"once_cell", "once_cell",
"serde", "serde",
"serde_yaml", "serde_yaml",
"signal-hook 0.3.8", "signal-hook 0.3.9",
"strip-ansi-escapes", "strip-ansi-escapes",
"structopt", "structopt",
"strum", "strum",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij" name = "zellij"
version = "0.13.0" version = "0.14.0"
authors = ["Aram Drevekenin <aram@poor.dev>"] authors = ["Aram Drevekenin <aram@poor.dev>"]
edition = "2018" edition = "2018"
description = "A terminal workspace with batteries included" description = "A terminal workspace with batteries included"
@ -14,15 +14,15 @@ resolver = "2"
[dependencies] [dependencies]
names = "0.11.0" names = "0.11.0"
zellij-client = { path = "zellij-client/", version = "0.13.0" } zellij-client = { path = "zellij-client/", version = "0.14.0" }
zellij-server = { path = "zellij-server/", version = "0.13.0" } zellij-server = { path = "zellij-server/", version = "0.14.0" }
zellij-utils = { path = "zellij-utils/", version = "0.13.0" } zellij-utils = { path = "zellij-utils/", version = "0.14.0" }
[dev-dependencies] [dev-dependencies]
insta = "1.6.0" insta = "1.6.0"
zellij-utils = { path = "zellij-utils/", version = "0.13.0", features = ["test"] } zellij-utils = { path = "zellij-utils/", version = "0.14.0", features = ["test"] }
zellij-client = { path = "zellij-client/", version = "0.13.0", features = ["test"] } zellij-client = { path = "zellij-client/", version = "0.14.0", features = ["test"] }
zellij-server = { path = "zellij-server/", version = "0.13.0", features = ["test"] } zellij-server = { path = "zellij-server/", version = "0.14.0", features = ["test"] }
[workspace] [workspace]
members = [ members = [
@ -57,3 +57,4 @@ assets = [
[features] [features]
disable_automatic_asset_installation = [] disable_automatic_asset_installation = []
parametric_resize_beta = []

View file

@ -82,7 +82,7 @@ end
''' '''
[tasks.build-plugins-release] [tasks.build-plugins-release]
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = ["."] } env = { "CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS" = ["default-plugins/status-bar", "default-plugins/strider", "default-plugins/tab-bar"] }
run_task = { name = "build-release", fork = true } run_task = { name = "build-release", fork = true }
[tasks.wasm-opt-plugins] [tasks.wasm-opt-plugins]
@ -129,15 +129,16 @@ args = ["install", "cross"]
[tasks.publish] [tasks.publish]
clear = true clear = true
workspace = false workspace = false
dependencies = ["build-plugins-release", "wasm-opt-plugins", "release-commit", "build-release", "publish-zellij-tile", "publish-zellij-tile-utils", "publish-zellij-utils", "publish-zellij-client", "publish-zellij-server"] dependencies = ["build-plugins-release", "wasm-opt-plugins", "release-commit"]
run_task = "publish-zellij" run_task = "publish-zellij"
[tasks.release-commit] [tasks.release-commit]
dependencies = ["commit-all", "tag-release"] dependencies = ["commit-all", "tag-release"]
command = "git" command = "git"
args = ["push", "--atomic", "upstream", "main", "v${CARGO_MAKE_CRATE_VERSION}"] args = ["push", "--atomic", "origin", "main", "v${CARGO_MAKE_CRATE_VERSION}"]
[tasks.commit-all] [tasks.commit-all]
ignore_errors = true
command = "git" command = "git"
args = ["commit", "-aem", "chore(release): v${CARGO_MAKE_CRATE_VERSION}"] args = ["commit", "-aem", "chore(release): v${CARGO_MAKE_CRATE_VERSION}"]
@ -148,35 +149,32 @@ args = ["tag", "v${CARGO_MAKE_CRATE_VERSION}"]
[tasks.publish-zellij-tile] [tasks.publish-zellij-tile]
ignore_errors = true ignore_errors = true
cwd = "zellij-tile" cwd = "zellij-tile"
command = "cargo" script = "cargo publish && sleep 15"
args = ["publish"]
[tasks.publish-zellij-client] [tasks.publish-zellij-client]
ignore_errors = true ignore_errors = true
dependencies = ["publish-zellij-utils"]
cwd = "zellij-client" cwd = "zellij-client"
command = "cargo" script = "cargo publish && sleep 15"
args = ["publish"]
[tasks.publish-zellij-server] [tasks.publish-zellij-server]
ignore_errors = true ignore_errors = true
dependencies = ["publish-zellij-utils"]
cwd = "zellij-server" cwd = "zellij-server"
command = "cargo" script = "cargo publish && sleep 15"
args = ["publish"]
[tasks.publish-zellij-utils] [tasks.publish-zellij-utils]
ignore_errors = true ignore_errors = true
dependencies = ["publish-zellij-tile"]
cwd = "zellij-utils" cwd = "zellij-utils"
command = "cargo" script = "cargo publish && sleep 15"
args = ["publish"]
[tasks.publish-zellij-tile-utils] [tasks.publish-zellij-tile-utils]
ignore_errors = true ignore_errors = true
cwd = "zellij-tile-utils" cwd = "zellij-tile-utils"
command = "cargo" script = "cargo publish && sleep 15"
args = ["publish"]
[tasks.publish-zellij] [tasks.publish-zellij]
dependencies = ["publish-zellij-client", "publish-zellij-server", "publish-zellij-utils"]
command = "cargo" command = "cargo"
args = ["publish"] args = ["publish"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -135,7 +135,7 @@ impl ZellijPlugin for State {
fn load(&mut self) { fn load(&mut self) {
set_selectable(false); set_selectable(false);
set_invisible_borders(true); set_invisible_borders(true);
set_max_height(2); set_fixed_height(2);
subscribe(&[EventType::ModeUpdate]); subscribe(&[EventType::ModeUpdate]);
} }

View file

@ -26,7 +26,7 @@ impl ZellijPlugin for State {
fn load(&mut self) { fn load(&mut self) {
set_selectable(false); set_selectable(false);
set_invisible_borders(true); set_invisible_borders(true);
set_max_height(1); set_fixed_height(1);
subscribe(&[EventType::TabUpdate, EventType::ModeUpdate]); subscribe(&[EventType::TabUpdate, EventType::ModeUpdate]);
} }
@ -57,7 +57,6 @@ impl ZellijPlugin for State {
let tab = tab_style( let tab = tab_style(
tabname, tabname,
t.active, t.active,
t.position,
t.is_sync_panes_active, t.is_sync_panes_active,
self.mode_info.palette, self.mode_info.palette,
self.mode_info.capabilities, self.mode_info.capabilities,

View file

@ -40,17 +40,12 @@ pub fn non_active_tab(text: String, palette: Palette, separator: &str) -> LinePa
pub fn tab_style( pub fn tab_style(
text: String, text: String,
is_active_tab: bool, is_active_tab: bool,
position: usize,
is_sync_panes_active: bool, is_sync_panes_active: bool,
palette: Palette, palette: Palette,
capabilities: PluginCapabilities, capabilities: PluginCapabilities,
) -> LinePart { ) -> LinePart {
let separator = tab_separator(capabilities); let separator = tab_separator(capabilities);
let mut tab_text = if text.is_empty() { let mut tab_text = text;
format!("Tab #{}", position + 1)
} else {
text
};
if is_sync_panes_active { if is_sync_panes_active {
tab_text.push_str(" (Sync)"); tab_text.push_str(" (Sync)");
} }

View file

@ -19,6 +19,7 @@ pub(crate) fn populate_data_dir(data_dir: &Path) {
let mut assets = asset_map! { let mut assets = asset_map! {
"assets/layouts/default.yaml" => "layouts/default.yaml", "assets/layouts/default.yaml" => "layouts/default.yaml",
"assets/layouts/strider.yaml" => "layouts/strider.yaml", "assets/layouts/strider.yaml" => "layouts/strider.yaml",
"assets/layouts/disable-status-bar.yaml" => "layouts/disable-status-bar.yaml",
}; };
assets.extend(asset_map! { assets.extend(asset_map! {
"assets/plugins/status-bar.wasm" => "plugins/status-bar.wasm", "assets/plugins/status-bar.wasm" => "plugins/status-bar.wasm",

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn starts_with_one_terminal() { pub fn starts_with_one_terminal() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -49,7 +49,7 @@ pub fn starts_with_one_terminal() {
#[test] #[test]
pub fn split_terminals_vertically() { pub fn split_terminals_vertically() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -78,7 +78,7 @@ pub fn split_terminals_vertically() {
#[test] #[test]
pub fn split_terminals_horizontally() { pub fn split_terminals_horizontally() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -108,7 +108,7 @@ pub fn split_terminals_horizontally() {
pub fn split_largest_terminal() { pub fn split_largest_terminal() {
// this finds the largest pane and splits along its longest edge (vertically or horizontally) // this finds the largest pane and splits along its longest edge (vertically or horizontally)
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -143,7 +143,7 @@ pub fn split_largest_terminal() {
#[test] #[test]
pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 8, cols: 8,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -172,7 +172,7 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
#[test] #[test]
pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() { pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 4, rows: 4,
x: 0, x: 0,
y: 0, y: 0,
@ -201,7 +201,7 @@ pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() {
#[test] #[test]
pub fn cannot_split_largest_terminal_when_there_is_no_room() { pub fn cannot_split_largest_terminal_when_there_is_no_room() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 8, cols: 8,
rows: 4, rows: 4,
x: 0, x: 0,
y: 0, y: 0,
@ -230,7 +230,7 @@ pub fn cannot_split_largest_terminal_when_there_is_no_room() {
#[test] #[test]
pub fn scrolling_up_inside_a_pane() { pub fn scrolling_up_inside_a_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -267,7 +267,7 @@ pub fn scrolling_up_inside_a_pane() {
#[test] #[test]
pub fn scrolling_down_inside_a_pane() { pub fn scrolling_down_inside_a_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -306,7 +306,7 @@ pub fn scrolling_down_inside_a_pane() {
#[test] #[test]
pub fn scrolling_page_up_inside_a_pane() { pub fn scrolling_page_up_inside_a_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -342,7 +342,7 @@ pub fn scrolling_page_up_inside_a_pane() {
#[test] #[test]
pub fn scrolling_page_down_inside_a_pane() { pub fn scrolling_page_down_inside_a_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -383,7 +383,7 @@ pub fn max_panes() {
// with the --max-panes option, we only allow a certain amount of panes on screen // with the --max-panes option, we only allow a certain amount of panes on screen
// simultaneously, new panes beyond this limit will close older panes on screen // simultaneously, new panes beyond this limit will close older panes on screen
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -421,7 +421,7 @@ pub fn max_panes() {
#[test] #[test]
pub fn toggle_focused_pane_fullscreen() { pub fn toggle_focused_pane_fullscreen() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -465,7 +465,7 @@ pub fn bracketed_paste() {
// since it's inside a bracketed paste block, while the "QUIT" command is, since it is already // since it's inside a bracketed paste block, while the "QUIT" command is, since it is already
// past the block // past the block
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -28,7 +28,7 @@ pub fn close_pane_with_another_pane_above_it() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -71,7 +71,7 @@ pub fn close_pane_with_another_pane_below_it() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -113,7 +113,7 @@ pub fn close_pane_with_another_pane_to_the_left() {
// └─────┴─────┘ └──────────┘ // └─────┴─────┘ └──────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -154,7 +154,7 @@ pub fn close_pane_with_another_pane_to_the_right() {
// └─────┴─────┘ └──────────┘ // └─────┴─────┘ └──────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -198,7 +198,7 @@ pub fn close_pane_with_multiple_panes_above_it() {
// └───────────┘ └─────┴─────┘ // └───────────┘ └─────┴─────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -245,7 +245,7 @@ pub fn close_pane_with_multiple_panes_below_it() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -290,7 +290,7 @@ pub fn close_pane_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └──────────┘ // └─────┴─────┘ └──────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -337,7 +337,7 @@ pub fn close_pane_with_multiple_panes_to_the_right() {
// └─────┴─────┘ └──────────┘ // └─────┴─────┘ └──────────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -382,7 +382,7 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() {
// └───┴───────┴───┘ └───┴───┴───┴───┘ // └───┴───────┴───┘ └───┴───┴───┴───┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -450,7 +450,7 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() {
// └───┴───┴───┴───┘ └───┴───┴───┴───┘ // └───┴───┴───┴───┘ └───┴───┴───┴───┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -516,7 +516,7 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() {
// └────┴──────┘ └────┴──────┘ // └────┴──────┘ └────┴──────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 30, rows: 30,
x: 0, x: 0,
y: 0, y: 0,
@ -582,7 +582,7 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
// └────┴──────┘ └────┴──────┘ // └────┴──────┘ └────┴──────┘
// █ == pane being closed // █ == pane being closed
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 30, rows: 30,
x: 0, x: 0,
y: 0, y: 0,
@ -638,7 +638,7 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
#[test] #[test]
pub fn closing_last_pane_exits_app() { pub fn closing_last_pane_exits_app() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -27,14 +27,14 @@ use zellij_utils::input::config::Config;
fn get_fake_os_input(fake_win_size: &PositionAndSize, fixture_name: &str) -> FakeInputOutput { fn get_fake_os_input(fake_win_size: &PositionAndSize, fixture_name: &str) -> FakeInputOutput {
let mut tty_inputs = HashMap::new(); let mut tty_inputs = HashMap::new();
let fixture_bytes = Bytes::from_file_in_fixtures(&fixture_name); let fixture_bytes = Bytes::from_file_in_fixtures(&fixture_name);
tty_inputs.insert(fake_win_size.columns as u16, fixture_bytes); tty_inputs.insert(fake_win_size.cols as u16, fixture_bytes);
FakeInputOutput::new(fake_win_size.clone()).with_tty_inputs(tty_inputs) FakeInputOutput::new(fake_win_size.clone()).with_tty_inputs(tty_inputs)
} }
#[test] #[test]
pub fn run_bandwhich_from_fish_shell() { pub fn run_bandwhich_from_fish_shell() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -65,7 +65,7 @@ pub fn run_bandwhich_from_fish_shell() {
#[test] #[test]
pub fn fish_tab_completion_options() { pub fn fish_tab_completion_options() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -100,7 +100,7 @@ pub fn fish_select_tab_completion_options() {
// this is not clearly seen in the snapshot because it does not include styles, // this is not clearly seen in the snapshot because it does not include styles,
// but we can see the command line change and the cursor staying in place // but we can see the command line change and the cursor staying in place
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -139,7 +139,7 @@ pub fn vim_scroll_region_down() {
// file // file
// experience appear to the user // experience appear to the user
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -175,7 +175,7 @@ pub fn vim_ctrl_d() {
// end of the scroll region // end of the scroll region
// vim makes sure to fill these empty lines with the rest of the file // vim makes sure to fill these empty lines with the rest of the file
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -210,7 +210,7 @@ pub fn vim_ctrl_u() {
// this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the // this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the
// file above the current content) // file above the current content)
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -240,7 +240,7 @@ pub fn vim_ctrl_u() {
#[test] #[test]
pub fn htop() { pub fn htop() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -270,7 +270,7 @@ pub fn htop() {
#[test] #[test]
pub fn htop_scrolling() { pub fn htop_scrolling() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -300,7 +300,7 @@ pub fn htop_scrolling() {
#[test] #[test]
pub fn htop_right_scrolling() { pub fn htop_right_scrolling() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -338,7 +338,7 @@ pub fn vim_overwrite() {
// * confirm you would like to change the file by pressing 'y' and then ENTER // * confirm you would like to change the file by pressing 'y' and then ENTER
// * if everything looks fine, this test passed :) // * if everything looks fine, this test passed :)
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -371,7 +371,7 @@ pub fn clear_scroll_region() {
// this means that when vim exits, we get back the previous scroll // this means that when vim exits, we get back the previous scroll
// buffer // buffer
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -401,7 +401,7 @@ pub fn clear_scroll_region() {
#[test] #[test]
pub fn display_tab_characters_properly() { pub fn display_tab_characters_properly() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -431,7 +431,7 @@ pub fn display_tab_characters_properly() {
#[test] #[test]
pub fn neovim_insert_mode() { pub fn neovim_insert_mode() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -463,7 +463,7 @@ pub fn bash_cursor_linewrap() {
// this test makes sure that when we enter a command that is beyond the screen border, that it // this test makes sure that when we enter a command that is beyond the screen border, that it
// immediately goes down one line // immediately goes down one line
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 116, cols: 116,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -495,7 +495,7 @@ pub fn fish_paste_multiline() {
// here we paste a multiline command in fish shell, making sure we support it // here we paste a multiline command in fish shell, making sure we support it
// going up and changing the colors of our line-wrapped pasted text // going up and changing the colors of our line-wrapped pasted text
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 149, cols: 149,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -525,7 +525,7 @@ pub fn fish_paste_multiline() {
#[test] #[test]
pub fn git_log() { pub fn git_log() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 149, cols: 149,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -557,7 +557,7 @@ pub fn git_diff_scrollup() {
// this tests makes sure that when we have a git diff that exceeds the screen size // this tests makes sure that when we have a git diff that exceeds the screen size
// we are able to scroll up // we are able to scroll up
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 149, cols: 149,
rows: 28, rows: 28,
x: 0, x: 0,
y: 0, y: 0,
@ -587,7 +587,7 @@ pub fn git_diff_scrollup() {
#[test] #[test]
pub fn emacs_longbuf() { pub fn emacs_longbuf() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 284, cols: 284,
rows: 60, rows: 60,
x: 0, x: 0,
y: 0, y: 0,
@ -617,7 +617,7 @@ pub fn emacs_longbuf() {
#[test] #[test]
pub fn top_and_quit() { pub fn top_and_quit() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 235, cols: 235,
rows: 56, rows: 56,
x: 0, x: 0,
y: 0, y: 0,
@ -653,7 +653,7 @@ pub fn exa_plus_omf_theme() {
// over existing on-screen content without deleting it, so we must // over existing on-screen content without deleting it, so we must
// convert it to spaces // convert it to spaces
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 235, cols: 235,
rows: 56, rows: 56,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -16,7 +16,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn accepts_basic_layout() { pub fn accepts_basic_layout() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn move_focus_down() { pub fn move_focus_down() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -55,7 +55,7 @@ pub fn move_focus_down() {
#[test] #[test]
pub fn move_focus_down_to_the_most_recently_used_pane() { pub fn move_focus_down_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn move_focus_left() { pub fn move_focus_left() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -55,7 +55,7 @@ pub fn move_focus_left() {
#[test] #[test]
pub fn move_focus_left_to_the_most_recently_used_pane() { pub fn move_focus_left_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -94,7 +94,7 @@ pub fn move_focus_left_to_the_most_recently_used_pane() {
#[test] #[test]
pub fn move_focus_left_changes_tab() { pub fn move_focus_left_changes_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn move_focus_right() { pub fn move_focus_right() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -56,7 +56,7 @@ pub fn move_focus_right() {
#[test] #[test]
pub fn move_focus_right_to_the_most_recently_used_pane() { pub fn move_focus_right_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -94,7 +94,7 @@ pub fn move_focus_right_to_the_most_recently_used_pane() {
#[test] #[test]
pub fn move_focus_right_changes_tab() { pub fn move_focus_right_changes_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn move_focus_up() { pub fn move_focus_up() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -54,7 +54,7 @@ pub fn move_focus_up() {
#[test] #[test]
pub fn move_focus_up_to_the_most_recently_used_pane() { pub fn move_focus_up_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -29,7 +29,7 @@ pub fn resize_down_with_pane_above() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -74,7 +74,7 @@ pub fn resize_down_with_pane_below() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -124,7 +124,7 @@ pub fn resize_down_with_panes_above_and_below() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 25, rows: 25,
x: 0, x: 0,
y: 0, y: 0,
@ -172,7 +172,7 @@ pub fn resize_down_with_multiple_panes_above() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -223,7 +223,7 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -276,7 +276,7 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -328,7 +328,7 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -378,7 +378,7 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -429,7 +429,7 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘ // └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -484,7 +484,7 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘ // └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -541,7 +541,7 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef
// └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘ // └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -616,7 +616,7 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_
// └─┴───────┴─┘ └─┴───────┴─┘ // └─┴───────┴─┘ └─┴───────┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -690,7 +690,7 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 7, rows: 7,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -25,7 +25,7 @@ pub fn resize_left_with_pane_to_the_left() {
// └─────┴─────┘ └───┴───────┘ // └─────┴─────┘ └───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -68,7 +68,7 @@ pub fn resize_left_with_pane_to_the_right() {
// └─────┴─────┘ └───┴───────┘ // └─────┴─────┘ └───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -112,7 +112,7 @@ pub fn resize_left_with_panes_to_the_left_and_right() {
// └─────┴─────┴─────┘ └─────┴───┴───────┘ // └─────┴─────┴─────┘ └─────┴───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -158,7 +158,7 @@ pub fn resize_left_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └───┴───────┘ // └─────┴─────┘ └───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -207,7 +207,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() {
// └─────┴─────┘ └───┴───────┘ // └─────┴─────┘ └───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -258,7 +258,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() {
// └─────┴─────┘ └───┴───────┘ // └─────┴─────┘ └───┴───────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -306,7 +306,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -356,7 +356,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -407,7 +407,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -462,7 +462,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -519,7 +519,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -594,7 +594,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
// TODO: combine with above // TODO: combine with above
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -667,7 +667,7 @@ pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() {
// └─┴─┘ └─┴─┘ // └─┴─┘ └─┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 9, cols: 9,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -25,7 +25,7 @@ pub fn resize_right_with_pane_to_the_left() {
// └─────┴─────┘ └───────┴───┘ // └─────┴─────┘ └───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -68,7 +68,7 @@ pub fn resize_right_with_pane_to_the_right() {
// └─────┴─────┘ └───────┴───┘ // └─────┴─────┘ └───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -112,7 +112,7 @@ pub fn resize_right_with_panes_to_the_left_and_right() {
// └─────┴─────┴─────┘ └─────┴───────┴───┘ // └─────┴─────┴─────┘ └─────┴───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -158,7 +158,7 @@ pub fn resize_right_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └───────┴───┘ // └─────┴─────┘ └───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -207,7 +207,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() {
// └─────┴─────┘ └───────┴───┘ // └─────┴─────┘ └───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -258,7 +258,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() {
// └─────┴─────┘ └───────┴───┘ // └─────┴─────┘ └───────┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -306,7 +306,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -356,7 +356,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -407,7 +407,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -462,7 +462,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -519,7 +519,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -593,7 +593,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -666,7 +666,7 @@ pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() {
// └─┴─┘ └─┴─┘ // └─┴─┘ └─┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 9, cols: 9,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -27,7 +27,7 @@ pub fn resize_up_with_pane_above() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -72,7 +72,7 @@ pub fn resize_up_with_pane_below() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -121,7 +121,7 @@ pub fn resize_up_with_panes_above_and_below() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -168,7 +168,7 @@ pub fn resize_up_with_multiple_panes_above() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -217,7 +217,7 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -270,7 +270,7 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -322,7 +322,7 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -372,7 +372,7 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘ // └─────┴─────┘ └─────┴─────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -423,7 +423,7 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘ // └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -478,7 +478,7 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘ // └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -535,7 +535,7 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_
// └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘ // └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -610,7 +610,7 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri
// └─┴───────┴─┘ └─┴───────┴─┘ // └─┴───────┴─┘ └─┴───────┴─┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 40, rows: 40,
x: 0, x: 0,
y: 0, y: 0,
@ -684,7 +684,7 @@ pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() {
// └───────────┘ └───────────┘ // └───────────┘ └───────────┘
// █ == focused pane // █ == focused pane
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 7, rows: 7,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -21,7 +21,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn open_new_tab() { pub fn open_new_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -57,7 +57,7 @@ pub fn open_new_tab() {
#[test] #[test]
pub fn switch_to_prev_tab() { pub fn switch_to_prev_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -94,7 +94,7 @@ pub fn switch_to_prev_tab() {
#[test] #[test]
pub fn switch_to_next_tab() { pub fn switch_to_next_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -131,7 +131,7 @@ pub fn switch_to_next_tab() {
#[test] #[test]
pub fn close_tab() { pub fn close_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -168,7 +168,7 @@ pub fn close_tab() {
#[test] #[test]
pub fn close_last_pane_in_a_tab() { pub fn close_last_pane_in_a_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -206,7 +206,7 @@ pub fn close_last_pane_in_a_tab() {
#[test] #[test]
pub fn close_the_middle_tab() { pub fn close_the_middle_tab() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -246,7 +246,7 @@ pub fn close_the_middle_tab() {
#[test] #[test]
pub fn close_the_tab_that_has_a_pane_in_fullscreen() { pub fn close_the_tab_that_has_a_pane_in_fullscreen() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -291,7 +291,7 @@ pub fn close_the_tab_that_has_a_pane_in_fullscreen() {
#[test] #[test]
pub fn closing_last_tab_exits_the_app() { pub fn closing_last_tab_exits_the_app() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -15,7 +15,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn window_width_decrease_with_one_pane() { pub fn window_width_decrease_with_one_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -24,7 +24,7 @@ pub fn window_width_decrease_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size); let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]); fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize { fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 90, cols: 90,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -52,7 +52,7 @@ pub fn window_width_decrease_with_one_pane() {
#[test] #[test]
pub fn window_width_increase_with_one_pane() { pub fn window_width_increase_with_one_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -61,7 +61,7 @@ pub fn window_width_increase_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size); let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]); fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize { fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 141, cols: 141,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -89,7 +89,7 @@ pub fn window_width_increase_with_one_pane() {
#[test] #[test]
pub fn window_height_increase_with_one_pane() { pub fn window_height_increase_with_one_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -98,7 +98,7 @@ pub fn window_height_increase_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size); let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]); fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize { fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 121, cols: 121,
rows: 30, rows: 30,
x: 0, x: 0,
y: 0, y: 0,
@ -126,7 +126,7 @@ pub fn window_height_increase_with_one_pane() {
#[test] #[test]
pub fn window_width_and_height_decrease_with_one_pane() { pub fn window_width_and_height_decrease_with_one_pane() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -135,7 +135,7 @@ pub fn window_width_and_height_decrease_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size); let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]); fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize { fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 90, cols: 90,
rows: 10, rows: 10,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test] #[test]
pub fn adding_new_terminal_in_fullscreen() { pub fn adding_new_terminal_in_fullscreen() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,
@ -55,7 +55,7 @@ pub fn adding_new_terminal_in_fullscreen() {
#[test] #[test]
pub fn move_focus_is_disabled_in_fullscreen() { pub fn move_focus_is_disabled_in_fullscreen() {
let fake_win_size = PositionAndSize { let fake_win_size = PositionAndSize {
columns: 121, cols: 121,
rows: 20, rows: 20,
x: 0, x: 0,
y: 0, y: 0,

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij-client" name = "zellij-client"
version = "0.13.0" version = "0.14.0"
authors = ["Kunal Mohan <kunalmohan99@gmail.com>"] authors = ["Kunal Mohan <kunalmohan99@gmail.com>"]
edition = "2018" edition = "2018"
description = "The client-side library for Zellij" description = "The client-side library for Zellij"
@ -10,7 +10,7 @@ license = "MIT"
[dependencies] [dependencies]
termbg = "0.2.3" termbg = "0.2.3"
zellij-utils = { path = "../zellij-utils/", version = "0.13.0" } zellij-utils = { path = "../zellij-utils/", version = "0.14.0" }
[features] [features]
test = ["zellij-utils/test"] test = ["zellij-utils/test"]

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij-server" name = "zellij-server"
version = "0.13.0" version = "0.14.0"
authors = ["Kunal Mohan <kunalmohan99@gmail.com>"] authors = ["Kunal Mohan <kunalmohan99@gmail.com>"]
edition = "2018" edition = "2018"
description = "The server-side library for Zellij" description = "The server-side library for Zellij"
@ -16,7 +16,8 @@ serde_json = "1.0"
unicode-width = "0.1.8" unicode-width = "0.1.8"
wasmer = "1.0.0" wasmer = "1.0.0"
wasmer-wasi = "1.0.0" wasmer-wasi = "1.0.0"
zellij-utils = { path = "../zellij-utils/", version = "0.13.0" } cassowary = "0.3.0"
zellij-utils = { path = "../zellij-utils/", version = "0.14.0" }
[dev-dependencies] [dev-dependencies]
insta = "1.6.0" insta = "1.6.0"

View file

@ -112,6 +112,8 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
daemonize::Daemonize::new() daemonize::Daemonize::new()
.working_directory(std::env::current_dir().unwrap()) .working_directory(std::env::current_dir().unwrap())
.umask(0o077) .umask(0o077)
// FIXME: My cherished `dbg!` was broken, so this is a hack to bring it back
//.stderr(std::fs::File::create("dbg.log").unwrap())
.start() .start()
.expect("could not daemonize the server process"); .expect("could not daemonize the server process");

View file

@ -95,10 +95,9 @@ fn transfer_rows_down(
next_lines.push(next_line); next_lines.push(next_line);
next_lines.append(&mut top_non_canonical_rows_in_dst); next_lines.append(&mut top_non_canonical_rows_in_dst);
next_lines = match max_dst_width { next_lines = match max_dst_width {
Some(max_row_width) => { Some(max_row_width) => Row::from_rows(next_lines, max_row_width)
Row::from_rows(next_lines).split_to_rows_of_length(max_row_width) .split_to_rows_of_length(max_row_width),
} None => vec![Row::from_rows(next_lines, 0)],
None => vec![Row::from_rows(next_lines)],
}; };
if next_lines.is_empty() { if next_lines.is_empty() {
// no more lines at source, the line we popped was probably empty // no more lines at source, the line we popped was probably empty
@ -114,11 +113,12 @@ fn transfer_rows_down(
if !next_lines.is_empty() { if !next_lines.is_empty() {
match max_src_width { match max_src_width {
Some(max_row_width) => { Some(max_row_width) => {
let excess_rows = Row::from_rows(next_lines).split_to_rows_of_length(max_row_width); let excess_rows = Row::from_rows(next_lines, max_row_width)
.split_to_rows_of_length(max_row_width);
source.extend(excess_rows); source.extend(excess_rows);
} }
None => { None => {
let excess_row = Row::from_rows(next_lines); let excess_row = Row::from_rows(next_lines, 0);
bounded_push(source, excess_row); bounded_push(source, excess_row);
} }
} }
@ -144,10 +144,9 @@ fn transfer_rows_up(
} }
next_lines.push(next_line); next_lines.push(next_line);
next_lines = match max_dst_width { next_lines = match max_dst_width {
Some(max_row_width) => { Some(max_row_width) => Row::from_rows(next_lines, max_row_width)
Row::from_rows(next_lines).split_to_rows_of_length(max_row_width) .split_to_rows_of_length(max_row_width),
} None => vec![Row::from_rows(next_lines, 0)],
None => vec![Row::from_rows(next_lines)],
}; };
} else { } else {
break; // no more rows break; // no more rows
@ -158,13 +157,14 @@ fn transfer_rows_up(
if !next_lines.is_empty() { if !next_lines.is_empty() {
match max_src_width { match max_src_width {
Some(max_row_width) => { Some(max_row_width) => {
let excess_rows = Row::from_rows(next_lines).split_to_rows_of_length(max_row_width); let excess_rows = Row::from_rows(next_lines, max_row_width)
.split_to_rows_of_length(max_row_width);
for row in excess_rows { for row in excess_rows {
source.insert(0, row); source.insert(0, row);
} }
} }
None => { None => {
let excess_row = Row::from_rows(next_lines); let excess_row = Row::from_rows(next_lines, 0);
source.insert(0, excess_row); source.insert(0, excess_row);
} }
} }
@ -191,6 +191,107 @@ pub fn create_horizontal_tabstops(columns: usize) -> BTreeSet<usize> {
horizontal_tabstops horizontal_tabstops
} }
#[derive(Debug)]
pub struct CharacterChunk {
pub terminal_characters: Vec<TerminalCharacter>,
pub x: usize,
pub y: usize,
}
#[derive(Clone, Debug)]
pub struct OutputBuffer {
changed_lines: Vec<usize>, // line index
should_update_all_lines: bool,
}
impl Default for OutputBuffer {
fn default() -> Self {
OutputBuffer {
changed_lines: vec![],
should_update_all_lines: true, // first time we should do a full render
}
}
}
impl OutputBuffer {
pub fn update_line(&mut self, line_index: usize) {
if !self.should_update_all_lines {
self.changed_lines.push(line_index);
}
}
pub fn update_all_lines(&mut self) {
self.clear();
self.should_update_all_lines = true;
}
pub fn clear(&mut self) {
self.changed_lines.clear();
self.should_update_all_lines = false;
}
pub fn changed_chunks_in_viewport(
&self,
viewport: &[Row],
viewport_width: usize,
viewport_height: usize,
) -> Vec<CharacterChunk> {
if self.should_update_all_lines {
let mut changed_chunks = Vec::with_capacity(viewport.len());
for line_index in 0..viewport_height {
let terminal_characters =
self.extract_line_from_viewport(line_index, viewport, viewport_width);
changed_chunks.push(CharacterChunk {
x: 0,
y: line_index,
terminal_characters,
});
}
changed_chunks
} else {
let mut line_changes = self.changed_lines.to_vec();
line_changes.sort_unstable();
line_changes.dedup();
let mut changed_chunks = Vec::with_capacity(line_changes.len());
for line_index in line_changes {
let terminal_characters =
self.extract_line_from_viewport(line_index, viewport, viewport_width);
changed_chunks.push(CharacterChunk {
x: 0,
y: line_index,
terminal_characters,
});
}
changed_chunks
}
}
fn extract_characters_from_row(
&self,
row: &Row,
viewport_width: usize,
) -> Vec<TerminalCharacter> {
let mut terminal_characters: Vec<TerminalCharacter> = row.columns.iter().copied().collect();
// pad row
let row_width = row.width();
if row_width < viewport_width {
let mut padding = vec![EMPTY_TERMINAL_CHARACTER; viewport_width - row_width];
terminal_characters.append(&mut padding);
}
terminal_characters
}
fn extract_line_from_viewport(
&self,
line_index: usize,
viewport: &[Row],
viewport_width: usize,
) -> Vec<TerminalCharacter> {
match viewport.get(line_index) {
// TODO: iterator?
Some(row) => self.extract_characters_from_row(row, viewport_width),
None => {
vec![EMPTY_TERMINAL_CHARACTER; viewport_width]
}
}
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct Grid { pub struct Grid {
lines_above: VecDeque<Row>, lines_above: VecDeque<Row>,
@ -204,6 +305,7 @@ pub struct Grid {
active_charset: CharsetIndex, active_charset: CharsetIndex,
preceding_char: Option<TerminalCharacter>, preceding_char: Option<TerminalCharacter>,
colors: Palette, colors: Palette,
output_buffer: OutputBuffer,
pub should_render: bool, pub should_render: bool,
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "") pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "")
pub erasure_mode: bool, // ERM pub erasure_mode: bool, // ERM
@ -232,7 +334,7 @@ impl Grid {
pub fn new(rows: usize, columns: usize, colors: Palette) -> Self { pub fn new(rows: usize, columns: usize, colors: Palette) -> Self {
Grid { Grid {
lines_above: VecDeque::with_capacity(SCROLL_BACK), lines_above: VecDeque::with_capacity(SCROLL_BACK),
viewport: vec![Row::new().canonical()], viewport: vec![Row::new(columns).canonical()],
lines_below: vec![], lines_below: vec![],
horizontal_tabstops: create_horizontal_tabstops(columns), horizontal_tabstops: create_horizontal_tabstops(columns),
cursor: Cursor::new(0, 0), cursor: Cursor::new(0, 0),
@ -251,8 +353,12 @@ impl Grid {
active_charset: Default::default(), active_charset: Default::default(),
pending_messages_to_pty: vec![], pending_messages_to_pty: vec![],
colors, colors,
output_buffer: Default::default(),
} }
} }
pub fn render_full_viewport(&mut self) {
self.output_buffer.update_all_lines();
}
pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) { pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) {
let mut next_tabstop = None; let mut next_tabstop = None;
for tabstop in self.horizontal_tabstops.iter() { for tabstop in self.horizontal_tabstops.iter() {
@ -272,6 +378,7 @@ impl Grid {
let mut empty_character = EMPTY_TERMINAL_CHARACTER; let mut empty_character = EMPTY_TERMINAL_CHARACTER;
empty_character.styles = styles; empty_character.styles = styles;
self.pad_current_line_until(self.cursor.x); self.pad_current_line_until(self.cursor.x);
self.output_buffer.update_line(self.cursor.y);
} }
pub fn move_to_previous_tabstop(&mut self) { pub fn move_to_previous_tabstop(&mut self) {
let mut previous_tabstop = None; let mut previous_tabstop = None;
@ -367,6 +474,7 @@ impl Grid {
let line_to_insert_at_viewport_top = self.lines_above.pop_back().unwrap(); let line_to_insert_at_viewport_top = self.lines_above.pop_back().unwrap();
self.viewport.insert(0, line_to_insert_at_viewport_top); self.viewport.insert(0, line_to_insert_at_viewport_top);
} }
self.output_buffer.update_all_lines();
} }
pub fn scroll_down_one_line(&mut self) { pub fn scroll_down_one_line(&mut self) {
if !self.lines_below.is_empty() && self.viewport.len() == self.height { if !self.lines_below.is_empty() && self.viewport.len() == self.height {
@ -380,6 +488,7 @@ impl Grid {
} }
let line_to_insert_at_viewport_bottom = self.lines_below.remove(0); let line_to_insert_at_viewport_bottom = self.lines_below.remove(0);
self.viewport.push(line_to_insert_at_viewport_bottom); self.viewport.push(line_to_insert_at_viewport_bottom);
self.output_buffer.update_all_lines();
} }
} }
pub fn change_size(&mut self, new_rows: usize, new_columns: usize) { pub fn change_size(&mut self, new_rows: usize, new_columns: usize) {
@ -417,7 +526,7 @@ impl Grid {
for mut canonical_line in viewport_canonical_lines { for mut canonical_line in viewport_canonical_lines {
let mut canonical_line_parts: Vec<Row> = vec![]; let mut canonical_line_parts: Vec<Row> = vec![];
if canonical_line.columns.is_empty() { if canonical_line.columns.is_empty() {
canonical_line_parts.push(Row::new().canonical()); canonical_line_parts.push(Row::new(new_columns).canonical());
} }
while !canonical_line.columns.is_empty() { while !canonical_line.columns.is_empty() {
let next_wrap = if canonical_line.width() > new_columns { let next_wrap = if canonical_line.width() > new_columns {
@ -515,8 +624,12 @@ impl Grid {
if self.scroll_region.is_some() { if self.scroll_region.is_some() {
self.set_scroll_region_to_viewport_size(); self.set_scroll_region_to_viewport_size();
} }
self.output_buffer.update_all_lines();
} }
pub fn as_character_lines(&self) -> Vec<Vec<TerminalCharacter>> { pub fn as_character_lines(&self) -> Vec<Vec<TerminalCharacter>> {
// this is only used in the tests
// it's not part of testing the app, but rather is used to interpret the snapshots created
// by it
let mut lines: Vec<Vec<TerminalCharacter>> = self let mut lines: Vec<Vec<TerminalCharacter>> = self
.viewport .viewport
.iter() .iter()
@ -537,6 +650,13 @@ impl Grid {
} }
lines lines
} }
pub fn read_changes(&mut self) -> Vec<CharacterChunk> {
let changes =
self.output_buffer
.changed_chunks_in_viewport(&self.viewport, self.width, self.height);
self.output_buffer.clear();
changes
}
pub fn cursor_coordinates(&self) -> Option<(usize, usize)> { pub fn cursor_coordinates(&self) -> Option<(usize, usize)> {
if self.cursor.is_hidden { if self.cursor.is_hidden {
None None
@ -548,17 +668,22 @@ impl Grid {
for _ in 0..count { for _ in 0..count {
self.scroll_up_one_line(); self.scroll_up_one_line();
} }
self.output_buffer.update_all_lines();
} }
pub fn move_viewport_down(&mut self, count: usize) { pub fn move_viewport_down(&mut self, count: usize) {
for _ in 0..count { for _ in 0..count {
self.scroll_down_one_line(); self.scroll_down_one_line();
} }
self.output_buffer.update_all_lines();
} }
pub fn reset_viewport(&mut self) { pub fn reset_viewport(&mut self) {
let row_count_below = self.lines_below.len(); let row_count_below = self.lines_below.len();
for _ in 0..row_count_below { for _ in 0..row_count_below {
self.scroll_down_one_line(); self.scroll_down_one_line();
} }
if row_count_below > 0 {
self.output_buffer.update_all_lines();
}
} }
pub fn rotate_scroll_region_up(&mut self, count: usize) { pub fn rotate_scroll_region_up(&mut self, count: usize) {
if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region {
@ -572,6 +697,7 @@ impl Grid {
.insert(scroll_region_top, Row::from_columns(columns).canonical()); .insert(scroll_region_top, Row::from_columns(columns).canonical());
} }
} }
self.output_buffer.update_all_lines(); // TODO: only update scroll region lines
} }
} }
pub fn rotate_scroll_region_down(&mut self, count: usize) { pub fn rotate_scroll_region_down(&mut self, count: usize) {
@ -586,6 +712,7 @@ impl Grid {
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
} }
} }
self.output_buffer.update_all_lines(); // TODO: only update scroll region lines
} }
} }
pub fn fill_viewport(&mut self, character: TerminalCharacter) { pub fn fill_viewport(&mut self, character: TerminalCharacter) {
@ -594,6 +721,7 @@ impl Grid {
let columns = vec![character; self.width]; let columns = vec![character; self.width];
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
} }
self.output_buffer.update_all_lines();
} }
pub fn add_canonical_line(&mut self) { pub fn add_canonical_line(&mut self) {
if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region {
@ -616,6 +744,7 @@ impl Grid {
} else { } else {
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
} }
self.output_buffer.update_all_lines(); // TODO: only update scroll region lines
return; return;
} }
} }
@ -623,7 +752,7 @@ impl Grid {
// FIXME: this should add an empty line with the pad_character // FIXME: this should add an empty line with the pad_character
// but for some reason this breaks rendering in various situations // but for some reason this breaks rendering in various situations
// it needs to be investigated and fixed // it needs to be investigated and fixed
let new_row = Row::new().canonical(); let new_row = Row::new(self.width).canonical();
self.viewport.push(new_row); self.viewport.push(new_row);
} }
if self.cursor.y == self.height - 1 { if self.cursor.y == self.height - 1 {
@ -635,8 +764,10 @@ impl Grid {
Some(self.width), Some(self.width),
None, None,
); );
self.output_buffer.update_all_lines();
} else { } else {
self.cursor.y += 1; self.cursor.y += 1;
self.output_buffer.update_line(self.cursor.y);
} }
} }
pub fn move_cursor_to_beginning_of_line(&mut self) { pub fn move_cursor_to_beginning_of_line(&mut self) {
@ -646,25 +777,26 @@ impl Grid {
match self.viewport.get_mut(self.cursor.y) { match self.viewport.get_mut(self.cursor.y) {
Some(row) => { Some(row) => {
row.insert_character_at(terminal_character, self.cursor.x); row.insert_character_at(terminal_character, self.cursor.x);
if row.len() > self.width { if row.width() > self.width {
row.truncate(self.width); row.truncate(self.width);
} }
self.output_buffer.update_line(self.cursor.y);
} }
None => { None => {
// pad lines until cursor if they do not exist // pad lines until cursor if they do not exist
for _ in self.viewport.len()..self.cursor.y { for _ in self.viewport.len()..self.cursor.y {
self.viewport.push(Row::new().canonical()); self.viewport.push(Row::new(self.width).canonical());
} }
self.viewport self.viewport.push(
.push(Row::new().with_character(terminal_character).canonical()); Row::new(self.width)
.with_character(terminal_character)
.canonical(),
);
self.output_buffer.update_all_lines();
} }
} }
} }
pub fn add_character_at_cursor_position( pub fn add_character_at_cursor_position(&mut self, terminal_character: TerminalCharacter) {
&mut self,
terminal_character: TerminalCharacter,
max_width: usize,
) {
match self.viewport.get_mut(self.cursor.y) { match self.viewport.get_mut(self.cursor.y) {
Some(row) => { Some(row) => {
if self.insert_mode { if self.insert_mode {
@ -672,15 +804,19 @@ impl Grid {
} else { } else {
row.add_character_at(terminal_character, self.cursor.x); row.add_character_at(terminal_character, self.cursor.x);
} }
row.truncate(max_width); self.output_buffer.update_line(self.cursor.y);
} }
None => { None => {
// pad lines until cursor if they do not exist // pad lines until cursor if they do not exist
for _ in self.viewport.len()..self.cursor.y { for _ in self.viewport.len()..self.cursor.y {
self.viewport.push(Row::new().canonical()); self.viewport.push(Row::new(self.width).canonical());
} }
self.viewport self.viewport.push(
.push(Row::new().with_character(terminal_character).canonical()); Row::new(self.width)
.with_character(terminal_character)
.canonical(),
);
self.output_buffer.update_line(self.cursor.y);
} }
} }
} }
@ -702,17 +838,19 @@ impl Grid {
Some(self.width), Some(self.width),
None, None,
); );
let wrapped_row = Row::new(); let wrapped_row = Row::new(self.width);
self.viewport.push(wrapped_row); self.viewport.push(wrapped_row);
self.output_buffer.update_all_lines();
} else { } else {
self.cursor.y += 1; self.cursor.y += 1;
if self.viewport.len() <= self.cursor.y { if self.viewport.len() <= self.cursor.y {
let line_wrapped_row = Row::new(); let line_wrapped_row = Row::new(self.width);
self.viewport.push(line_wrapped_row); self.viewport.push(line_wrapped_row);
self.output_buffer.update_line(self.cursor.y);
} }
} }
} }
self.add_character_at_cursor_position(terminal_character, self.width); self.add_character_at_cursor_position(terminal_character);
self.move_cursor_forward_until_edge(character_width); self.move_cursor_forward_until_edge(character_width);
} }
pub fn move_cursor_forward_until_edge(&mut self, count: usize) { pub fn move_cursor_forward_until_edge(&mut self, count: usize) {
@ -724,10 +862,12 @@ impl Grid {
.get_mut(self.cursor.y) .get_mut(self.cursor.y)
.unwrap() .unwrap()
.replace_and_pad_end(self.cursor.x, self.width, replace_with); .replace_and_pad_end(self.cursor.x, self.width, replace_with);
self.output_buffer.update_line(self.cursor.y);
} }
pub fn replace_characters_in_line_before_cursor(&mut self, replace_with: TerminalCharacter) { pub fn replace_characters_in_line_before_cursor(&mut self, replace_with: TerminalCharacter) {
let row = self.viewport.get_mut(self.cursor.y).unwrap(); let row = self.viewport.get_mut(self.cursor.y).unwrap();
row.replace_and_pad_beginning(self.cursor.x, replace_with); row.replace_and_pad_beginning(self.cursor.x, replace_with);
self.output_buffer.update_line(self.cursor.y);
} }
pub fn clear_all_after_cursor(&mut self, replace_with: TerminalCharacter) { pub fn clear_all_after_cursor(&mut self, replace_with: TerminalCharacter) {
if let Some(cursor_row) = self.viewport.get_mut(self.cursor.y) { if let Some(cursor_row) = self.viewport.get_mut(self.cursor.y) {
@ -737,6 +877,7 @@ impl Grid {
for row in self.viewport.iter_mut().skip(self.cursor.y + 1) { for row in self.viewport.iter_mut().skip(self.cursor.y + 1) {
row.replace_columns(replace_with_columns.clone()); row.replace_columns(replace_with_columns.clone());
} }
self.output_buffer.update_all_lines(); // TODO: only update the changed lines
} }
} }
pub fn clear_all_before_cursor(&mut self, replace_with: TerminalCharacter) { pub fn clear_all_before_cursor(&mut self, replace_with: TerminalCharacter) {
@ -746,10 +887,12 @@ impl Grid {
for row in self.viewport.iter_mut().take(self.cursor.y) { for row in self.viewport.iter_mut().take(self.cursor.y) {
row.replace_columns(replace_with_columns.clone()); row.replace_columns(replace_with_columns.clone());
} }
self.output_buffer.update_all_lines(); // TODO: only update the changed lines
} }
} }
pub fn clear_cursor_line(&mut self) { pub fn clear_cursor_line(&mut self) {
self.viewport.get_mut(self.cursor.y).unwrap().truncate(0); self.viewport.get_mut(self.cursor.y).unwrap().truncate(0);
self.output_buffer.update_line(self.cursor.y);
} }
pub fn clear_all(&mut self, replace_with: TerminalCharacter) { pub fn clear_all(&mut self, replace_with: TerminalCharacter) {
let replace_with_columns = vec![replace_with; self.width]; let replace_with_columns = vec![replace_with; self.width];
@ -757,17 +900,20 @@ impl Grid {
for row in self.viewport.iter_mut() { for row in self.viewport.iter_mut() {
row.replace_columns(replace_with_columns.clone()); row.replace_columns(replace_with_columns.clone());
} }
self.output_buffer.update_all_lines();
} }
fn pad_current_line_until(&mut self, position: usize) { fn pad_current_line_until(&mut self, position: usize) {
let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); let current_row = self.viewport.get_mut(self.cursor.y).unwrap();
for _ in current_row.len()..position { for _ in current_row.len()..position {
current_row.push(EMPTY_TERMINAL_CHARACTER); current_row.push(EMPTY_TERMINAL_CHARACTER);
} }
self.output_buffer.update_line(self.cursor.y);
} }
fn pad_lines_until(&mut self, position: usize, pad_character: TerminalCharacter) { fn pad_lines_until(&mut self, position: usize, pad_character: TerminalCharacter) {
for _ in self.viewport.len()..=position { for _ in self.viewport.len()..=position {
let columns = vec![pad_character; self.width]; let columns = vec![pad_character; self.width];
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
self.output_buffer.update_line(self.viewport.len() - 1);
} }
} }
pub fn move_cursor_to(&mut self, x: usize, y: usize, pad_character: TerminalCharacter) { pub fn move_cursor_to(&mut self, x: usize, y: usize, pad_character: TerminalCharacter) {
@ -816,13 +962,15 @@ impl Grid {
if scroll_region_bottom < self.viewport.len() { if scroll_region_bottom < self.viewport.len() {
self.viewport.remove(scroll_region_bottom); self.viewport.remove(scroll_region_bottom);
} }
self.viewport.insert(current_line_index, Row::new()); // TODO: .canonical() ? self.viewport
.insert(current_line_index, Row::new(self.width)); // TODO: .canonical() ?
} else if current_line_index > scroll_region_top } else if current_line_index > scroll_region_top
&& current_line_index <= scroll_region_bottom && current_line_index <= scroll_region_bottom
{ {
self.move_cursor_up(count); self.move_cursor_up(count);
} }
} }
self.output_buffer.update_all_lines();
} }
pub fn move_cursor_down(&mut self, count: usize, pad_character: TerminalCharacter) { pub fn move_cursor_down(&mut self, count: usize, pad_character: TerminalCharacter) {
if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region {
@ -896,6 +1044,7 @@ impl Grid {
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
} }
} }
self.output_buffer.update_all_lines(); // TODO: move accurately
} }
} }
} }
@ -920,6 +1069,7 @@ impl Grid {
self.viewport self.viewport
.insert(current_line_index, Row::from_columns(columns).canonical()); .insert(current_line_index, Row::from_columns(columns).canonical());
} }
self.output_buffer.update_all_lines(); // TODO: move accurately
} }
} }
} }
@ -941,6 +1091,7 @@ impl Grid {
for i in 0..count { for i in 0..count {
current_row.replace_character_at(empty_character, self.cursor.x + i); current_row.replace_character_at(empty_character, self.cursor.x + i);
} }
self.output_buffer.update_line(self.cursor.y);
} }
pub fn erase_characters(&mut self, count: usize, empty_char_style: CharacterStyles) { pub fn erase_characters(&mut self, count: usize, empty_char_style: CharacterStyles) {
let mut empty_character = EMPTY_TERMINAL_CHARACTER; let mut empty_character = EMPTY_TERMINAL_CHARACTER;
@ -956,6 +1107,7 @@ impl Grid {
current_row.insert_character_at(empty_character, self.cursor.x); current_row.insert_character_at(empty_character, self.cursor.x);
} }
} }
self.output_buffer.update_line(self.cursor.y);
} }
fn add_newline(&mut self) { fn add_newline(&mut self) {
self.add_canonical_line(); self.add_canonical_line();
@ -967,7 +1119,7 @@ impl Grid {
fn reset_terminal_state(&mut self) { fn reset_terminal_state(&mut self) {
self.lines_above = VecDeque::with_capacity(SCROLL_BACK); self.lines_above = VecDeque::with_capacity(SCROLL_BACK);
self.lines_below = vec![]; self.lines_below = vec![];
self.viewport = vec![Row::new().canonical()]; self.viewport = vec![Row::new(self.width).canonical()];
self.alternative_lines_above_viewport_and_cursor = None; self.alternative_lines_above_viewport_and_cursor = None;
self.cursor_key_mode = false; self.cursor_key_mode = false;
self.scroll_region = None; self.scroll_region = None;
@ -978,6 +1130,7 @@ impl Grid {
self.erasure_mode = false; self.erasure_mode = false;
self.disable_linewrap = false; self.disable_linewrap = false;
self.cursor.change_shape(CursorShape::Block); self.cursor.change_shape(CursorShape::Block);
self.output_buffer.update_all_lines();
} }
fn set_preceding_character(&mut self, terminal_character: TerminalCharacter) { fn set_preceding_character(&mut self, terminal_character: TerminalCharacter) {
self.preceding_char = Some(terminal_character); self.preceding_char = Some(terminal_character);
@ -1306,8 +1459,10 @@ impl Perform for Grid {
&mut self.lines_above, &mut self.lines_above,
VecDeque::with_capacity(SCROLL_BACK), VecDeque::with_capacity(SCROLL_BACK),
); );
let current_viewport = let current_viewport = std::mem::replace(
std::mem::replace(&mut self.viewport, vec![Row::new().canonical()]); &mut self.viewport,
vec![Row::new(self.width).canonical()],
);
let current_cursor = std::mem::replace(&mut self.cursor, Cursor::new(0, 0)); let current_cursor = std::mem::replace(&mut self.cursor, Cursor::new(0, 0));
self.alternative_lines_above_viewport_and_cursor = self.alternative_lines_above_viewport_and_cursor =
Some((current_lines_above, current_viewport, current_cursor)); Some((current_lines_above, current_viewport, current_cursor));
@ -1594,28 +1749,22 @@ impl Debug for Row {
} }
} }
impl Default for Row { impl Row {
fn default() -> Self { pub fn new(width: usize) -> Self {
Row { Row {
columns: vec![], columns: Vec::with_capacity(width),
is_canonical: false, is_canonical: false,
} }
} }
}
impl Row {
pub fn new() -> Self {
Self::default()
}
pub fn from_columns(columns: Vec<TerminalCharacter>) -> Self { pub fn from_columns(columns: Vec<TerminalCharacter>) -> Self {
Row { Row {
columns, columns,
is_canonical: false, is_canonical: false,
} }
} }
pub fn from_rows(mut rows: Vec<Row>) -> Self { pub fn from_rows(mut rows: Vec<Row>, width: usize) -> Self {
if rows.is_empty() { if rows.is_empty() {
Row::new() Row::new(width)
} else { } else {
let mut first_row = rows.remove(0); let mut first_row = rows.remove(0);
for row in rows.iter_mut() { for row in rows.iter_mut() {
@ -1670,9 +1819,18 @@ impl Row {
} }
Ordering::Greater => { Ordering::Greater => {
let width_offset = self.excess_width_until(x); let width_offset = self.excess_width_until(x);
// this is much more performant than remove/insert let character_width = terminal_character.width;
self.columns.push(terminal_character); let replaced_character = std::mem::replace(
self.columns.swap_remove(x.saturating_sub(width_offset)); &mut self.columns[x.saturating_sub(width_offset)],
terminal_character,
);
if character_width > replaced_character.width {
// this is done in a verbose manner because of performance
let width_difference = character_width - replaced_character.width;
for _ in 0..width_difference {
self.columns.pop();
}
}
} }
} }
} }

View file

@ -16,8 +16,6 @@ pub(crate) struct PluginPane {
pub position_and_size: PositionAndSize, pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>, pub position_and_size_override: Option<PositionAndSize>,
pub send_plugin_instructions: SenderWithContext<PluginInstruction>, pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
pub max_height: Option<usize>,
pub max_width: Option<usize>,
pub active_at: Instant, pub active_at: Instant,
} }
@ -35,8 +33,6 @@ impl PluginPane {
position_and_size, position_and_size,
position_and_size_override: None, position_and_size_override: None,
send_plugin_instructions, send_plugin_instructions,
max_height: None,
max_width: None,
active_at: Instant::now(), active_at: Instant::now(),
} }
} }
@ -64,7 +60,7 @@ impl Pane for PluginPane {
fn columns(&self) -> usize { fn columns(&self) -> usize {
self.position_and_size_override self.position_and_size_override
.unwrap_or(self.position_and_size) .unwrap_or(self.position_and_size)
.columns .cols
} }
fn reset_size_and_position_override(&mut self) { fn reset_size_and_position_override(&mut self) {
self.position_and_size_override = None; self.position_and_size_override = None;
@ -80,7 +76,7 @@ impl Pane for PluginPane {
x, x,
y, y,
rows: size.rows, rows: size.rows,
columns: size.columns, cols: size.cols,
..Default::default() ..Default::default()
}; };
self.position_and_size_override = Some(position_and_size_override); self.position_and_size_override = Some(position_and_size_override);
@ -95,7 +91,9 @@ impl Pane for PluginPane {
fn adjust_input_to_terminal(&self, _input_bytes: Vec<u8>) -> Vec<u8> { fn adjust_input_to_terminal(&self, _input_bytes: Vec<u8>) -> Vec<u8> {
unimplemented!() // FIXME: Shouldn't need this implmented? unimplemented!() // FIXME: Shouldn't need this implmented?
} }
fn position_and_size(&self) -> PositionAndSize {
self.position_and_size
}
fn position_and_size_override(&self) -> Option<PositionAndSize> { fn position_and_size_override(&self) -> Option<PositionAndSize> {
self.position_and_size_override self.position_and_size_override
} }
@ -114,11 +112,13 @@ impl Pane for PluginPane {
fn set_invisible_borders(&mut self, invisible_borders: bool) { fn set_invisible_borders(&mut self, invisible_borders: bool) {
self.invisible_borders = invisible_borders; self.invisible_borders = invisible_borders;
} }
fn set_max_height(&mut self, max_height: usize) { fn set_fixed_height(&mut self, fixed_height: usize) {
self.max_height = Some(max_height); self.position_and_size.rows = fixed_height;
self.position_and_size.rows_fixed = true;
} }
fn set_max_width(&mut self, max_width: usize) { fn set_fixed_width(&mut self, fixed_width: usize) {
self.max_width = Some(max_width); self.position_and_size.cols = fixed_width;
self.position_and_size.cols_fixed = true;
} }
fn render(&mut self) -> Option<String> { fn render(&mut self) -> Option<String> {
// if self.should_render { // if self.should_render {
@ -167,20 +167,20 @@ impl Pane for PluginPane {
} }
fn reduce_width_right(&mut self, count: usize) { fn reduce_width_right(&mut self, count: usize) {
self.position_and_size.x += count; self.position_and_size.x += count;
self.position_and_size.columns -= count; self.position_and_size.cols -= count;
self.should_render = true; self.should_render = true;
} }
fn reduce_width_left(&mut self, count: usize) { fn reduce_width_left(&mut self, count: usize) {
self.position_and_size.columns -= count; self.position_and_size.cols -= count;
self.should_render = true; self.should_render = true;
} }
fn increase_width_left(&mut self, count: usize) { fn increase_width_left(&mut self, count: usize) {
self.position_and_size.x -= count; self.position_and_size.x -= count;
self.position_and_size.columns += count; self.position_and_size.cols += count;
self.should_render = true; self.should_render = true;
} }
fn increase_width_right(&mut self, count: usize) { fn increase_width_right(&mut self, count: usize) {
self.position_and_size.columns += count; self.position_and_size.cols += count;
self.should_render = true; self.should_render = true;
} }
fn push_down(&mut self, count: usize) { fn push_down(&mut self, count: usize) {
@ -204,11 +204,21 @@ impl Pane for PluginPane {
fn clear_scroll(&mut self) { fn clear_scroll(&mut self) {
unimplemented!() unimplemented!()
} }
// FIXME: This need to be reevaluated and deleted if possible.
// `max` doesn't make sense when things are fixed...
fn max_height(&self) -> Option<usize> { fn max_height(&self) -> Option<usize> {
self.max_height if self.position_and_size.rows_fixed {
Some(self.position_and_size.rows)
} else {
None
}
} }
fn max_width(&self) -> Option<usize> { fn max_width(&self) -> Option<usize> {
self.max_width if self.position_and_size.cols_fixed {
Some(self.position_and_size.cols)
} else {
None
}
} }
fn invisible_borders(&self) -> bool { fn invisible_borders(&self) -> bool {
self.invisible_borders self.invisible_borders

View file

@ -27,8 +27,6 @@ pub struct TerminalPane {
pub selectable: bool, pub selectable: bool,
pub position_and_size: PositionAndSize, pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>, pub position_and_size_override: Option<PositionAndSize>,
pub max_height: Option<usize>,
pub max_width: Option<usize>,
pub active_at: Instant, pub active_at: Instant,
pub colors: Palette, pub colors: Palette,
vte_parser: vte::Parser, vte_parser: vte::Parser,
@ -52,8 +50,7 @@ impl Pane for TerminalPane {
self.reflow_lines(); self.reflow_lines();
} }
fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) { fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) {
self.position_and_size.columns = position_and_size.columns; self.position_and_size = *position_and_size;
self.position_and_size.rows = position_and_size.rows;
self.reflow_lines(); self.reflow_lines();
} }
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) { fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
@ -61,7 +58,7 @@ impl Pane for TerminalPane {
x, x,
y, y,
rows: size.rows, rows: size.rows,
columns: size.columns, cols: size.cols,
..Default::default() ..Default::default()
}; };
self.position_and_size_override = Some(position_and_size_override); self.position_and_size_override = Some(position_and_size_override);
@ -119,7 +116,9 @@ impl Pane for TerminalPane {
}; };
input_bytes input_bytes
} }
fn position_and_size(&self) -> PositionAndSize {
self.position_and_size
}
fn position_and_size_override(&self) -> Option<PositionAndSize> { fn position_and_size_override(&self) -> Option<PositionAndSize> {
self.position_and_size_override self.position_and_size_override
} }
@ -129,32 +128,29 @@ impl Pane for TerminalPane {
fn set_should_render(&mut self, should_render: bool) { fn set_should_render(&mut self, should_render: bool) {
self.grid.should_render = should_render; self.grid.should_render = should_render;
} }
fn render_full_viewport(&mut self) {
self.grid.render_full_viewport();
}
fn selectable(&self) -> bool { fn selectable(&self) -> bool {
self.selectable self.selectable
} }
fn set_selectable(&mut self, selectable: bool) { fn set_selectable(&mut self, selectable: bool) {
self.selectable = selectable; self.selectable = selectable;
} }
fn set_max_height(&mut self, max_height: usize) { fn set_fixed_height(&mut self, fixed_height: usize) {
self.max_height = Some(max_height); self.position_and_size.rows = fixed_height;
self.position_and_size.rows_fixed = true;
} }
fn set_max_width(&mut self, max_width: usize) { fn set_fixed_width(&mut self, fixed_width: usize) {
self.max_width = Some(max_width); self.position_and_size.cols = fixed_width;
self.position_and_size.cols_fixed = true;
} }
fn set_invisible_borders(&mut self, _invisible_borders: bool) { fn set_invisible_borders(&mut self, _invisible_borders: bool) {
unimplemented!(); unimplemented!();
} }
fn max_height(&self) -> Option<usize> {
self.max_height
}
fn max_width(&self) -> Option<usize> {
self.max_width
}
fn render(&mut self) -> Option<String> { fn render(&mut self) -> Option<String> {
if self.should_render() { if self.should_render() {
let mut vte_output = String::new(); let mut vte_output = String::new();
let buffer_lines = &self.read_buffer_as_lines();
let display_cols = self.get_columns();
let mut character_styles = CharacterStyles::new(); let mut character_styles = CharacterStyles::new();
if self.grid.clear_viewport_before_rendering { if self.grid.clear_viewport_before_rendering {
for line_index in 0..self.grid.height { for line_index in 0..self.grid.height {
@ -171,25 +167,31 @@ impl Pane for TerminalPane {
} }
self.grid.clear_viewport_before_rendering = false; self.grid.clear_viewport_before_rendering = false;
} }
for (row, line) in buffer_lines.iter().enumerate() { let max_width = self.columns();
let x = self.get_x(); for character_chunk in self.grid.read_changes() {
let y = self.get_y(); let pane_x = self.get_x();
vte_output.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", y + row + 1, x + 1)); // goto row/col and reset styles let pane_y = self.get_y();
for (col, t_character) in line.iter().enumerate() { let chunk_absolute_x = pane_x + character_chunk.x;
if col < display_cols { let chunk_absolute_y = pane_y + character_chunk.y;
// in some cases (eg. while resizing) some characters will spill over let terminal_characters = character_chunk.terminal_characters;
// before they are corrected by the shell (for the prompt) or by reflowing vte_output.push_str(&format!(
// lines "\u{1b}[{};{}H\u{1b}[m",
if let Some(new_styles) = chunk_absolute_y + 1,
character_styles.update_and_return_diff(&t_character.styles) chunk_absolute_x + 1
{ )); // goto row/col and reset styles
// the terminal keeps the previous styles as long as we're in the same
// line, so we only want to update the new styles here (this also let mut chunk_width = character_chunk.x;
// includes resetting previous styles as needed) for t_character in terminal_characters {
vte_output.push_str(&new_styles.to_string()); chunk_width += t_character.width;
} if chunk_width > max_width {
vte_output.push(t_character.character); break;
} }
if let Some(new_styles) =
character_styles.update_and_return_diff(&t_character.styles)
{
vte_output.push_str(&new_styles.to_string());
}
vte_output.push(t_character.character);
} }
character_styles.clear(); character_styles.clear();
} }
@ -222,20 +224,20 @@ impl Pane for TerminalPane {
} }
fn reduce_width_right(&mut self, count: usize) { fn reduce_width_right(&mut self, count: usize) {
self.position_and_size.x += count; self.position_and_size.x += count;
self.position_and_size.columns -= count; self.position_and_size.cols -= count;
self.reflow_lines(); self.reflow_lines();
} }
fn reduce_width_left(&mut self, count: usize) { fn reduce_width_left(&mut self, count: usize) {
self.position_and_size.columns -= count; self.position_and_size.cols -= count;
self.reflow_lines(); self.reflow_lines();
} }
fn increase_width_left(&mut self, count: usize) { fn increase_width_left(&mut self, count: usize) {
self.position_and_size.x -= count; self.position_and_size.x -= count;
self.position_and_size.columns += count; self.position_and_size.cols += count;
self.reflow_lines(); self.reflow_lines();
} }
fn increase_width_right(&mut self, count: usize) { fn increase_width_right(&mut self, count: usize) {
self.position_and_size.columns += count; self.position_and_size.cols += count;
self.reflow_lines(); self.reflow_lines();
} }
fn push_down(&mut self, count: usize) { fn push_down(&mut self, count: usize) {
@ -287,15 +289,13 @@ impl Pane for TerminalPane {
impl TerminalPane { impl TerminalPane {
pub fn new(pid: RawFd, position_and_size: PositionAndSize, palette: Palette) -> TerminalPane { pub fn new(pid: RawFd, position_and_size: PositionAndSize, palette: Palette) -> TerminalPane {
let grid = Grid::new(position_and_size.rows, position_and_size.columns, palette); let grid = Grid::new(position_and_size.rows, position_and_size.cols, palette);
TerminalPane { TerminalPane {
pid, pid,
grid, grid,
selectable: true, selectable: true,
position_and_size, position_and_size,
position_and_size_override: None, position_and_size_override: None,
max_height: None,
max_width: None,
vte_parser: vte::Parser::new(), vte_parser: vte::Parser::new(),
active_at: Instant::now(), active_at: Instant::now(),
colors: palette, colors: palette,
@ -315,8 +315,8 @@ impl TerminalPane {
} }
pub fn get_columns(&self) -> usize { pub fn get_columns(&self) -> usize {
match &self.position_and_size_override.as_ref() { match &self.position_and_size_override.as_ref() {
Some(position_and_size_override) => position_and_size_override.columns, Some(position_and_size_override) => position_and_size_override.cols,
None => self.position_and_size.columns as usize, None => self.position_and_size.cols as usize,
} }
} }
pub fn get_rows(&self) -> usize { pub fn get_rows(&self) -> usize {

View file

@ -3,7 +3,7 @@ source: zellij-server/src/panes/./unit/grid_tests.rs
expression: "format!(\"{:?}\", grid)" expression: "format!(\"{:?}\", grid)"
--- ---
00 (C): A******************************************************************************BAAAAAAAAAAAAAAAAA 00 (C): A******************************************************************************BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
01 (C): 01 (C):
02 (C): 02 (C):
03 (C): Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. Push <RETURN> 03 (C): Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. Push <RETURN>

View file

@ -3,7 +3,7 @@ source: zellij-server/src/panes/./unit/grid_tests.rs
expression: "format!(\"{:?}\", grid)" expression: "format!(\"{:?}\", grid)"
--- ---
00 (C): ABAAAAAAAAAAAAAAAAA 00 (C): ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
01 (C): 01 (C):
02 (C): 02 (C):
03 (C): Test of 'Delete Character'. The top line should be 'AB'. Push <RETURN> 03 (C): Test of 'Delete Character'. The top line should be 'AB'. Push <RETURN>

View file

@ -54,7 +54,8 @@ pub(crate) enum ScreenInstruction {
CloseFocusedPane, CloseFocusedPane,
ToggleActiveTerminalFullscreen, ToggleActiveTerminalFullscreen,
SetSelectable(PaneId, bool), SetSelectable(PaneId, bool),
SetMaxHeight(PaneId, usize), SetFixedHeight(PaneId, usize),
SetFixedWidth(PaneId, usize),
SetInvisibleBorders(PaneId, bool), SetInvisibleBorders(PaneId, bool),
ClosePane(PaneId), ClosePane(PaneId),
ApplyLayout(Layout, Vec<RawFd>), ApplyLayout(Layout, Vec<RawFd>),
@ -105,7 +106,8 @@ impl From<&ScreenInstruction> for ScreenContext {
} }
ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable, ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable,
ScreenInstruction::SetInvisibleBorders(..) => ScreenContext::SetInvisibleBorders, ScreenInstruction::SetInvisibleBorders(..) => ScreenContext::SetInvisibleBorders,
ScreenInstruction::SetMaxHeight(..) => ScreenContext::SetMaxHeight, ScreenInstruction::SetFixedHeight(..) => ScreenContext::SetFixedHeight,
ScreenInstruction::SetFixedWidth(..) => ScreenContext::SetFixedWidth,
ScreenInstruction::ClosePane(_) => ScreenContext::ClosePane, ScreenInstruction::ClosePane(_) => ScreenContext::ClosePane,
ScreenInstruction::ApplyLayout(..) => ScreenContext::ApplyLayout, ScreenInstruction::ApplyLayout(..) => ScreenContext::ApplyLayout,
ScreenInstruction::NewTab(_) => ScreenContext::NewTab, ScreenInstruction::NewTab(_) => ScreenContext::NewTab,
@ -573,11 +575,17 @@ pub(crate) fn screen_thread_main(
.unwrap() .unwrap()
.set_pane_selectable(id, selectable); .set_pane_selectable(id, selectable);
} }
ScreenInstruction::SetMaxHeight(id, max_height) => { ScreenInstruction::SetFixedHeight(id, fixed_height) => {
screen screen
.get_active_tab_mut() .get_active_tab_mut()
.unwrap() .unwrap()
.set_pane_max_height(id, max_height); .set_pane_fixed_height(id, fixed_height);
}
ScreenInstruction::SetFixedWidth(id, fixed_width) => {
screen
.get_active_tab_mut()
.unwrap()
.set_pane_fixed_width(id, fixed_width);
} }
ScreenInstruction::SetInvisibleBorders(id, invisible_borders) => { ScreenInstruction::SetInvisibleBorders(id, invisible_borders) => {
screen screen

View file

@ -3,12 +3,16 @@
use zellij_utils::{serde, zellij_tile}; use zellij_utils::{serde, zellij_tile};
#[cfg(not(feature = "parametric_resize_beta"))]
use crate::ui::pane_resizer::PaneResizer;
#[cfg(feature = "parametric_resize_beta")]
use crate::ui::pane_resizer_beta::PaneResizer;
use crate::{ use crate::{
os_input_output::ServerOsApi, os_input_output::ServerOsApi,
panes::{PaneId, PluginPane, TerminalPane}, panes::{PaneId, PluginPane, TerminalPane},
pty::{PtyInstruction, VteBytes}, pty::{PtyInstruction, VteBytes},
thread_bus::ThreadSenders, thread_bus::ThreadSenders,
ui::{boundaries::Boundaries, pane_resizer::PaneResizer}, ui::boundaries::Boundaries,
wasm_vm::PluginInstruction, wasm_vm::PluginInstruction,
ServerInstruction, SessionState, ServerInstruction, SessionState,
}; };
@ -37,16 +41,16 @@ const MIN_TERMINAL_WIDTH: usize = 4;
type BorderAndPaneIds = (usize, Vec<PaneId>); type BorderAndPaneIds = (usize, Vec<PaneId>);
fn split_vertically_with_gap(rect: &PositionAndSize) -> (PositionAndSize, PositionAndSize) { fn split_vertically_with_gap(rect: &PositionAndSize) -> (PositionAndSize, PositionAndSize) {
let width_of_each_half = (rect.columns - 1) / 2; let width_of_each_half = (rect.cols - 1) / 2;
let mut first_rect = *rect; let mut first_rect = *rect;
let mut second_rect = *rect; let mut second_rect = *rect;
if rect.columns % 2 == 0 { if rect.cols % 2 == 0 {
first_rect.columns = width_of_each_half + 1; first_rect.cols = width_of_each_half + 1;
} else { } else {
first_rect.columns = width_of_each_half; first_rect.cols = width_of_each_half;
} }
second_rect.x = first_rect.x + first_rect.columns + 1; second_rect.x = first_rect.x + first_rect.cols + 1;
second_rect.columns = width_of_each_half; second_rect.cols = width_of_each_half;
(first_rect, second_rect) (first_rect, second_rect)
} }
@ -108,15 +112,15 @@ pub trait Pane {
fn handle_pty_bytes(&mut self, bytes: VteBytes); fn handle_pty_bytes(&mut self, bytes: VteBytes);
fn cursor_coordinates(&self) -> Option<(usize, usize)>; fn cursor_coordinates(&self) -> Option<(usize, usize)>;
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8>; fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8>;
fn position_and_size(&self) -> PositionAndSize;
fn position_and_size_override(&self) -> Option<PositionAndSize>; fn position_and_size_override(&self) -> Option<PositionAndSize>;
fn should_render(&self) -> bool; fn should_render(&self) -> bool;
fn set_should_render(&mut self, should_render: bool); fn set_should_render(&mut self, should_render: bool);
fn selectable(&self) -> bool; fn selectable(&self) -> bool;
fn set_selectable(&mut self, selectable: bool); fn set_selectable(&mut self, selectable: bool);
fn set_invisible_borders(&mut self, invisible_borders: bool); fn set_invisible_borders(&mut self, invisible_borders: bool);
fn set_max_height(&mut self, max_height: usize); fn set_fixed_height(&mut self, fixed_height: usize);
fn set_max_width(&mut self, max_width: usize); fn set_fixed_width(&mut self, fixed_width: usize);
fn render(&mut self) -> Option<String>; fn render(&mut self) -> Option<String>;
fn pid(&self) -> PaneId; fn pid(&self) -> PaneId;
fn reduce_height_down(&mut self, count: usize); fn reduce_height_down(&mut self, count: usize);
@ -182,15 +186,6 @@ pub trait Pane {
std::cmp::min(self.x() + self.columns(), other.x() + other.columns()) std::cmp::min(self.x() + self.columns(), other.x() + other.columns())
- std::cmp::max(self.x(), other.x()) - std::cmp::max(self.x(), other.x())
} }
fn position_and_size(&self) -> PositionAndSize {
PositionAndSize {
x: self.x(),
y: self.y(),
columns: self.columns(),
rows: self.rows(),
..Default::default()
}
}
fn can_increase_height_by(&self, increase_by: usize) -> bool { fn can_increase_height_by(&self, increase_by: usize) -> bool {
self.max_height() self.max_height()
.map(|max_height| self.rows() + increase_by <= max_height) .map(|max_height| self.rows() + increase_by <= max_height)
@ -227,6 +222,7 @@ pub trait Pane {
// we should probably refactor away from this trait at some point // we should probably refactor away from this trait at some point
vec![] vec![]
} }
fn render_full_viewport(&mut self) {}
} }
impl Tab { impl Tab {
@ -259,6 +255,13 @@ impl Tab {
} else { } else {
BTreeMap::new() BTreeMap::new()
}; };
let name = if name.is_empty() {
format!("Tab #{}", position + 1)
} else {
name
};
Tab { Tab {
index, index,
position, position,
@ -286,7 +289,7 @@ impl Tab {
x: 0, x: 0,
y: 0, y: 0,
rows: self.full_screen_ws.rows, rows: self.full_screen_ws.rows,
columns: self.full_screen_ws.columns, cols: self.full_screen_ws.cols,
..Default::default() ..Default::default()
}; };
self.panes_to_hide.clear(); self.panes_to_hide.clear();
@ -298,16 +301,10 @@ impl Tab {
match positions_and_size.next() { match positions_and_size.next() {
Some((_, position_and_size)) => { Some((_, position_and_size)) => {
terminal_pane.reset_size_and_position_override(); terminal_pane.reset_size_and_position_override();
if let Some(max_rows) = position_and_size.max_rows {
terminal_pane.set_max_height(max_rows);
}
if let Some(max_columns) = position_and_size.max_columns {
terminal_pane.set_max_width(max_columns);
}
terminal_pane.change_pos_and_size(&position_and_size); terminal_pane.change_pos_and_size(&position_and_size);
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
*pid, *pid,
position_and_size.columns as u16, position_and_size.cols as u16,
position_and_size.rows as u16, position_and_size.rows as u16,
); );
} }
@ -321,24 +318,18 @@ impl Tab {
} }
let mut new_pids = new_pids.iter(); let mut new_pids = new_pids.iter();
for (layout, position_and_size) in positions_and_size { for (layout, position_and_size) in positions_and_size {
// Just a regular terminal // A plugin pane
if let Some(plugin) = &layout.plugin { if let Some(plugin) = &layout.plugin {
let (pid_tx, pid_rx) = channel(); let (pid_tx, pid_rx) = channel();
self.senders self.senders
.send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone())) .send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone()))
.unwrap(); .unwrap();
let pid = pid_rx.recv().unwrap(); let pid = pid_rx.recv().unwrap();
let mut new_plugin = PluginPane::new( let new_plugin = PluginPane::new(
pid, pid,
*position_and_size, *position_and_size,
self.senders.to_plugin.as_ref().unwrap().clone(), self.senders.to_plugin.as_ref().unwrap().clone(),
); );
if let Some(max_rows) = position_and_size.max_rows {
new_plugin.set_max_height(max_rows);
}
if let Some(max_columns) = position_and_size.max_columns {
new_plugin.set_max_width(max_columns);
}
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin)); self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
// Send an initial mode update to the newly loaded plugin only! // Send an initial mode update to the newly loaded plugin only!
self.senders self.senders
@ -418,7 +409,7 @@ impl Tab {
let terminal_to_split = self.panes.get_mut(&terminal_id_to_split).unwrap(); let terminal_to_split = self.panes.get_mut(&terminal_id_to_split).unwrap();
let terminal_ws = PositionAndSize { let terminal_ws = PositionAndSize {
rows: terminal_to_split.rows(), rows: terminal_to_split.rows(),
columns: terminal_to_split.columns(), cols: terminal_to_split.columns(),
x: terminal_to_split.x(), x: terminal_to_split.x(),
y: terminal_to_split.y(), y: terminal_to_split.y(),
..Default::default() ..Default::default()
@ -431,7 +422,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors); let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
new_terminal.pid, new_terminal.pid,
bottom_winsize.columns as u16, bottom_winsize.cols as u16,
bottom_winsize.rows as u16, bottom_winsize.rows as u16,
); );
terminal_to_split.change_pos_and_size(&top_winsize); terminal_to_split.change_pos_and_size(&top_winsize);
@ -439,7 +430,7 @@ impl Tab {
if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split { if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split {
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
terminal_id_to_split, terminal_id_to_split,
top_winsize.columns as u16, top_winsize.cols as u16,
top_winsize.rows as u16, top_winsize.rows as u16,
); );
} }
@ -451,7 +442,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors); let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
new_terminal.pid, new_terminal.pid,
right_winsize.columns as u16, right_winsize.cols as u16,
right_winsize.rows as u16, right_winsize.rows as u16,
); );
terminal_to_split.change_pos_and_size(&left_winsize); terminal_to_split.change_pos_and_size(&left_winsize);
@ -459,7 +450,7 @@ impl Tab {
if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split { if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split {
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
terminal_id_to_split, terminal_id_to_split,
left_winsize.columns as u16, left_winsize.cols as u16,
left_winsize.rows as u16, left_winsize.rows as u16,
); );
} }
@ -499,7 +490,7 @@ impl Tab {
x: active_pane.x(), x: active_pane.x(),
y: active_pane.y(), y: active_pane.y(),
rows: active_pane.rows(), rows: active_pane.rows(),
columns: active_pane.columns(), cols: active_pane.columns(),
..Default::default() ..Default::default()
}; };
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws); let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
@ -509,7 +500,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors); let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
new_terminal.pid, new_terminal.pid,
bottom_winsize.columns as u16, bottom_winsize.cols as u16,
bottom_winsize.rows as u16, bottom_winsize.rows as u16,
); );
self.panes.insert(pid, Box::new(new_terminal)); self.panes.insert(pid, Box::new(new_terminal));
@ -517,7 +508,7 @@ impl Tab {
if let PaneId::Terminal(active_terminal_pid) = active_pane_id { if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
*active_terminal_pid, *active_terminal_pid,
top_winsize.columns as u16, top_winsize.cols as u16,
top_winsize.rows as u16, top_winsize.rows as u16,
); );
} }
@ -556,7 +547,7 @@ impl Tab {
x: active_pane.x(), x: active_pane.x(),
y: active_pane.y(), y: active_pane.y(),
rows: active_pane.rows(), rows: active_pane.rows(),
columns: active_pane.columns(), cols: active_pane.columns(),
..Default::default() ..Default::default()
}; };
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws); let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
@ -566,7 +557,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors); let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
new_terminal.pid, new_terminal.pid,
right_winsize.columns as u16, right_winsize.cols as u16,
right_winsize.rows as u16, right_winsize.rows as u16,
); );
self.panes.insert(pid, Box::new(new_terminal)); self.panes.insert(pid, Box::new(new_terminal));
@ -574,7 +565,7 @@ impl Tab {
if let PaneId::Terminal(active_terminal_pid) = active_pane_id { if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd( self.os_api.set_terminal_size_using_fd(
*active_terminal_pid, *active_terminal_pid,
left_winsize.columns as u16, left_winsize.cols as u16,
left_winsize.rows as u16, left_winsize.rows as u16,
); );
} }
@ -616,6 +607,7 @@ impl Tab {
for message in messages_to_pty { for message in messages_to_pty {
self.write_to_pane_id(message, PaneId::Terminal(pid)); self.write_to_pane_id(message, PaneId::Terminal(pid));
} }
// self.render();
} }
} }
pub fn write_to_terminals_on_current_tab(&mut self, input_bytes: Vec<u8>) { pub fn write_to_terminals_on_current_tab(&mut self, input_bytes: Vec<u8>) {
@ -704,6 +696,7 @@ impl Tab {
active_terminal.rows() as u16, active_terminal.rows() as u16,
); );
} }
self.set_force_render();
self.render(); self.render();
self.toggle_fullscreen_is_active(); self.toggle_fullscreen_is_active();
} }
@ -714,6 +707,7 @@ impl Tab {
pub fn set_force_render(&mut self) { pub fn set_force_render(&mut self) {
for pane in self.panes.values_mut() { for pane in self.panes.values_mut() {
pane.set_should_render(true); pane.set_should_render(true);
pane.render_full_viewport();
} }
} }
pub fn is_sync_panes_active(&self) -> bool { pub fn is_sync_panes_active(&self) -> bool {
@ -733,7 +727,7 @@ impl Tab {
} }
let mut output = String::new(); let mut output = String::new();
let mut boundaries = Boundaries::new( let mut boundaries = Boundaries::new(
self.full_screen_ws.columns as u16, self.full_screen_ws.cols as u16,
self.full_screen_ws.rows as u16, self.full_screen_ws.rows as u16,
); );
let hide_cursor = "\u{1b}[?25l"; let hide_cursor = "\u{1b}[?25l";
@ -1144,7 +1138,7 @@ impl Tab {
} }
} }
// rightmost border aligned with a pane border above // rightmost border aligned with a pane border above
let mut right_resize_border = self.full_screen_ws.columns; let mut right_resize_border = self.full_screen_ws.cols;
for terminal in &terminals { for terminal in &terminals {
let left_terminal_boundary = terminal.x(); let left_terminal_boundary = terminal.x();
if terminal_borders_above if terminal_borders_above
@ -1222,7 +1216,7 @@ impl Tab {
} }
} }
// leftmost border aligned with a pane border above // leftmost border aligned with a pane border above
let mut right_resize_border = self.full_screen_ws.columns; let mut right_resize_border = self.full_screen_ws.cols;
for terminal in &terminals { for terminal in &terminals {
let left_terminal_boundary = terminal.x(); let left_terminal_boundary = terminal.x();
if terminal_borders_below if terminal_borders_below
@ -1564,7 +1558,7 @@ impl Tab {
return false; return false;
} }
let mut new_pos_and_size_for_pane = pane.position_and_size(); let mut new_pos_and_size_for_pane = pane.position_and_size();
new_pos_and_size_for_pane.columns += increase_by; new_pos_and_size_for_pane.cols += increase_by;
if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) { if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) {
return panes_to_the_right.iter().all(|id| { return panes_to_the_right.iter().all(|id| {
@ -1732,8 +1726,8 @@ impl Tab {
.resize(self.full_screen_ws, new_screen_size) .resize(self.full_screen_ws, new_screen_size)
{ {
self.should_clear_display_before_rendering = true; self.should_clear_display_before_rendering = true;
self.full_screen_ws.columns = self.full_screen_ws.cols =
(self.full_screen_ws.columns as isize + column_difference) as usize; (self.full_screen_ws.cols as isize + column_difference) as usize;
self.full_screen_ws.rows = self.full_screen_ws.rows =
(self.full_screen_ws.rows as isize + row_difference) as usize; (self.full_screen_ws.rows as isize + row_difference) as usize;
}; };
@ -2125,9 +2119,14 @@ impl Tab {
pane.set_invisible_borders(invisible_borders); pane.set_invisible_borders(invisible_borders);
} }
} }
pub fn set_pane_max_height(&mut self, id: PaneId, max_height: usize) { pub fn set_pane_fixed_height(&mut self, id: PaneId, fixed_height: usize) {
if let Some(pane) = self.panes.get_mut(&id) { if let Some(pane) = self.panes.get_mut(&id) {
pane.set_max_height(max_height); pane.set_fixed_height(fixed_height);
}
}
pub fn set_pane_fixed_width(&mut self, id: PaneId, fixed_width: usize) {
if let Some(pane) = self.panes.get_mut(&id) {
pane.set_fixed_width(fixed_width);
} }
} }
pub fn close_pane(&mut self, id: PaneId) { pub fn close_pane(&mut self, id: PaneId) {

View file

@ -1,2 +1,3 @@
pub mod boundaries; pub mod boundaries;
pub mod pane_resizer; pub mod pane_resizer;
pub mod pane_resizer_beta;

View file

@ -29,37 +29,35 @@ impl<'a> PaneResizer<'a> {
let mut successfully_resized = false; let mut successfully_resized = false;
let mut column_difference: isize = 0; let mut column_difference: isize = 0;
let mut row_difference: isize = 0; let mut row_difference: isize = 0;
match new_size.columns.cmp(&current_size.columns) { match new_size.cols.cmp(&current_size.cols) {
Ordering::Greater => { Ordering::Greater => {
let increase_by = new_size.columns - current_size.columns; let increase_by = new_size.cols - current_size.cols;
if let Some(panes_to_resize) = find_increasable_vertical_chain( if let Some(panes_to_resize) = find_increasable_vertical_chain(
&self.panes, &self.panes,
increase_by, increase_by,
current_size.columns, current_size.cols,
current_size.rows, current_size.rows,
) { ) {
self.increase_panes_right_and_push_adjacents_right( self.increase_panes_right_and_push_adjacents_right(
panes_to_resize, panes_to_resize,
increase_by, increase_by,
); );
column_difference = new_size.columns as isize - current_size.columns as isize; column_difference = new_size.cols as isize - current_size.cols as isize;
current_size.columns = current_size.cols = (current_size.cols as isize + column_difference) as usize;
(current_size.columns as isize + column_difference) as usize;
successfully_resized = true; successfully_resized = true;
}; };
} }
Ordering::Less => { Ordering::Less => {
let reduce_by = current_size.columns - new_size.columns; let reduce_by = current_size.cols - new_size.cols;
if let Some(panes_to_resize) = find_reducible_vertical_chain( if let Some(panes_to_resize) = find_reducible_vertical_chain(
&self.panes, &self.panes,
reduce_by, reduce_by,
current_size.columns, current_size.cols,
current_size.rows, current_size.rows,
) { ) {
self.reduce_panes_left_and_pull_adjacents_left(panes_to_resize, reduce_by); self.reduce_panes_left_and_pull_adjacents_left(panes_to_resize, reduce_by);
column_difference = new_size.columns as isize - current_size.columns as isize; column_difference = new_size.cols as isize - current_size.cols as isize;
current_size.columns = current_size.cols = (current_size.cols as isize + column_difference) as usize;
(current_size.columns as isize + column_difference) as usize;
successfully_resized = true; successfully_resized = true;
}; };
} }
@ -71,7 +69,7 @@ impl<'a> PaneResizer<'a> {
if let Some(panes_to_resize) = find_increasable_horizontal_chain( if let Some(panes_to_resize) = find_increasable_horizontal_chain(
&self.panes, &self.panes,
increase_by, increase_by,
current_size.columns, current_size.cols,
current_size.rows, current_size.rows,
) { ) {
self.increase_panes_down_and_push_down_adjacents(panes_to_resize, increase_by); self.increase_panes_down_and_push_down_adjacents(panes_to_resize, increase_by);
@ -85,7 +83,7 @@ impl<'a> PaneResizer<'a> {
if let Some(panes_to_resize) = find_reducible_horizontal_chain( if let Some(panes_to_resize) = find_reducible_horizontal_chain(
&self.panes, &self.panes,
reduce_by, reduce_by,
current_size.columns, current_size.cols,
current_size.rows, current_size.rows,
) { ) {
self.reduce_panes_up_and_pull_adjacents_up(panes_to_resize, reduce_by); self.reduce_panes_up_and_pull_adjacents_up(panes_to_resize, reduce_by);

View file

@ -0,0 +1,248 @@
#![allow(dead_code)]
use crate::{os_input_output::ServerOsApi, panes::PaneId, tab::Pane};
use cassowary::{
strength::{REQUIRED, STRONG},
Constraint, Solver, Variable,
WeightedRelation::*,
};
use std::{
collections::{BTreeMap, HashSet},
ops::Not,
};
use zellij_utils::pane_size::PositionAndSize;
const GAP_SIZE: usize = 1; // Panes are separated by this number of rows / columns
pub struct PaneResizer<'a> {
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
vars: BTreeMap<PaneId, (Variable, Variable)>,
solver: Solver,
os_api: &'a mut Box<dyn ServerOsApi>,
}
#[derive(Debug, Clone, Copy)]
enum Direction {
Horizontal,
Vertical,
}
impl Not for Direction {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Direction::Horizontal => Direction::Vertical,
Direction::Vertical => Direction::Horizontal,
}
}
}
#[derive(Debug, Clone, Copy)]
struct Span {
pid: PaneId,
direction: Direction,
fixed: bool,
pos: usize,
size: usize,
pos_var: Variable,
size_var: Variable,
}
// TODO: currently there are some functions here duplicated with Tab
// all resizing functions should move here
// FIXME:
// 1. Rounding causes a loss of ratios, I need to store an internal f64 for
// each pane as well as the displayed usize and add custom rounding logic.
// 2. Vertical resizing doesn't seem to respect the space consumed by the tab
// and status bars?
// 3. A 2x2 layout and simultaneous vertical + horizontal resizing sometimes
// leads to unsolvable constraints? Maybe related to 2 (and possibly 1).
// I should sanity-check the `spans_in_boundary()` here!
impl<'a> PaneResizer<'a> {
pub fn new(
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
os_api: &'a mut Box<dyn ServerOsApi>,
) -> Self {
let mut vars = BTreeMap::new();
for &k in panes.keys() {
vars.insert(k, (Variable::new(), Variable::new()));
}
PaneResizer {
panes,
vars,
solver: Solver::new(),
os_api,
}
}
pub fn resize(
&mut self,
current_size: PositionAndSize,
new_size: PositionAndSize,
) -> Option<(isize, isize)> {
let col_delta = new_size.cols as isize - current_size.cols as isize;
let row_delta = new_size.rows as isize - current_size.rows as isize;
if col_delta != 0 {
let spans = self.solve_direction(Direction::Horizontal, new_size.cols)?;
self.collapse_spans(&spans);
}
self.solver.reset();
if row_delta != 0 {
let spans = self.solve_direction(Direction::Vertical, new_size.rows)?;
self.collapse_spans(&spans);
}
Some((col_delta, row_delta))
}
fn solve_direction(&mut self, direction: Direction, space: usize) -> Option<Vec<Span>> {
let mut grid = Vec::new();
for boundary in self.grid_boundaries(direction) {
grid.push(self.spans_in_boundary(direction, boundary));
}
let constraints: Vec<_> = grid
.iter()
.flat_map(|s| constrain_spans(space, s))
.collect();
// FIXME: This line needs to be restored before merging!
//self.solver.add_constraints(&constraints).ok()?;
self.solver.add_constraints(&constraints).unwrap();
Some(grid.into_iter().flatten().collect())
}
fn grid_boundaries(&self, direction: Direction) -> Vec<(usize, usize)> {
// Select the spans running *perpendicular* to the direction of resize
let spans: Vec<Span> = self
.panes
.values()
.map(|p| self.get_span(!direction, p.as_ref()))
.collect();
let mut last_edge = 0;
let mut bounds = Vec::new();
loop {
let mut spans_on_edge: Vec<&Span> =
spans.iter().filter(|p| p.pos == last_edge).collect();
spans_on_edge.sort_unstable_by_key(|s| s.size);
if let Some(next) = spans_on_edge.first() {
let next_edge = last_edge + next.size;
bounds.push((last_edge, next_edge));
last_edge = next_edge + GAP_SIZE;
} else {
break;
}
}
bounds
}
fn spans_in_boundary(&self, direction: Direction, boundary: (usize, usize)) -> Vec<Span> {
let (start, end) = boundary;
let bwn = |v| start <= v && v < end;
let mut spans: Vec<_> = self
.panes
.values()
.filter(|p| {
let s = self.get_span(!direction, p.as_ref());
bwn(s.pos) || bwn(s.pos + s.size)
})
.map(|p| self.get_span(direction, p.as_ref()))
.collect();
spans.sort_unstable_by_key(|s| s.pos);
spans
}
fn get_span(&self, direction: Direction, pane: &dyn Pane) -> Span {
let pas = pane.position_and_size();
let (pos_var, size_var) = self.vars[&pane.pid()];
match direction {
Direction::Horizontal => Span {
pid: pane.pid(),
direction,
fixed: pas.cols_fixed,
pos: pas.x,
size: pas.cols,
pos_var,
size_var,
},
Direction::Vertical => Span {
pid: pane.pid(),
direction,
fixed: pas.rows_fixed,
pos: pas.y,
size: pas.rows,
pos_var,
size_var,
},
}
}
fn collapse_spans(&mut self, spans: &[Span]) {
for span in spans {
let solver = &self.solver; // Hand-holding the borrow-checker
let pane = self.panes.get_mut(&span.pid).unwrap();
let fetch_usize = |v| solver.get_value(v).round() as usize;
match span.direction {
Direction::Horizontal => pane.change_pos_and_size(&PositionAndSize {
x: fetch_usize(span.pos_var),
cols: fetch_usize(span.size_var),
..pane.position_and_size()
}),
Direction::Vertical => pane.change_pos_and_size(&PositionAndSize {
y: fetch_usize(span.pos_var),
rows: fetch_usize(span.size_var),
..pane.position_and_size()
}),
}
if let PaneId::Terminal(pid) = pane.pid() {
self.os_api.set_terminal_size_using_fd(
pid,
pane.columns() as u16,
pane.rows() as u16,
);
}
}
}
}
fn constrain_spans(space: usize, spans: &[Span]) -> HashSet<Constraint> {
let mut constraints = HashSet::new();
// The first span needs to start at 0
constraints.insert(spans[0].pos_var | EQ(REQUIRED) | 0.0);
// Calculating "flexible" space (space not consumed by fixed-size spans)
let gap_space = GAP_SIZE * (spans.len() - 1);
let old_flex_space = spans
.iter()
.fold(0, |a, s| if !s.fixed { a + s.size } else { a });
let new_flex_space = spans.iter().fold(
space - gap_space,
|a, s| if s.fixed { a - s.size } else { a },
);
// Keep spans stuck together
for pair in spans.windows(2) {
let (ls, rs) = (pair[0], pair[1]);
constraints
.insert((ls.pos_var + ls.size_var + GAP_SIZE as f64) | EQ(REQUIRED) | rs.pos_var);
}
// Try to maintain ratios and lock non-flexible sizes
for span in spans {
if span.fixed {
constraints.insert(span.size_var | EQ(REQUIRED) | span.size as f64);
} else {
let ratio = span.size as f64 / old_flex_space as f64;
constraints.insert((span.size_var / new_flex_space as f64) | EQ(STRONG) | ratio);
}
}
// The last pane needs to end at the end of the space
let last = spans.last().unwrap();
constraints.insert((last.pos_var + last.size_var) | EQ(REQUIRED) | space as f64);
constraints
}

View file

@ -158,7 +158,8 @@ pub(crate) fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObj
host_subscribe, host_subscribe,
host_unsubscribe, host_unsubscribe,
host_set_invisible_borders, host_set_invisible_borders,
host_set_max_height, host_set_fixed_height,
host_set_fixed_width,
host_set_selectable, host_set_selectable,
host_get_plugin_ids, host_get_plugin_ids,
host_open_file, host_open_file,
@ -189,13 +190,24 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
.unwrap() .unwrap()
} }
fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { fn host_set_fixed_height(plugin_env: &PluginEnv, fixed_height: i32) {
let max_height = max_height as usize; let fixed_height = fixed_height as usize;
plugin_env plugin_env
.senders .senders
.send_to_screen(ScreenInstruction::SetMaxHeight( .send_to_screen(ScreenInstruction::SetFixedHeight(
PaneId::Plugin(plugin_env.plugin_id), PaneId::Plugin(plugin_env.plugin_id),
max_height, fixed_height,
))
.unwrap()
}
fn host_set_fixed_width(plugin_env: &PluginEnv, fixed_width: i32) {
let fixed_width = fixed_width as usize;
plugin_env
.senders
.send_to_screen(ScreenInstruction::SetFixedWidth(
PaneId::Plugin(plugin_env.plugin_id),
fixed_width,
)) ))
.unwrap() .unwrap()
} }

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij-tile-utils" name = "zellij-tile-utils"
version = "0.13.0" version = "0.14.0"
authors = ["denis <denismaximov98@gmail.com>"] authors = ["denis <denismaximov98@gmail.com>"]
edition = "2018" edition = "2018"
description = "A utility library for Zellij plugins" description = "A utility library for Zellij plugins"

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij-tile" name = "zellij-tile"
version = "0.13.0" version = "0.14.0"
authors = ["Brooks J Rady <b.j.rady@gmail.com>"] authors = ["Brooks J Rady <b.j.rady@gmail.com>"]
edition = "2018" edition = "2018"
description = "A small client-side library for writing Zellij plugins" description = "A small client-side library for writing Zellij plugins"

View file

@ -17,8 +17,12 @@ pub fn unsubscribe(event_types: &[EventType]) {
// Plugin Settings // Plugin Settings
pub fn set_max_height(max_height: i32) { pub fn set_fixed_height(fixed_height: i32) {
unsafe { host_set_max_height(max_height) }; unsafe { host_set_fixed_height(fixed_height) };
}
pub fn set_fixed_width(fixed_width: i32) {
unsafe { host_set_fixed_width(fixed_width) };
} }
pub fn set_selectable(selectable: bool) { pub fn set_selectable(selectable: bool) {
@ -64,7 +68,8 @@ pub fn object_to_stdout(object: &impl Serialize) {
extern "C" { extern "C" {
fn host_subscribe(); fn host_subscribe();
fn host_unsubscribe(); fn host_unsubscribe();
fn host_set_max_height(max_height: i32); fn host_set_fixed_height(fixed_height: i32);
fn host_set_fixed_width(fixed_width: i32);
fn host_set_selectable(selectable: i32); fn host_set_selectable(selectable: i32);
fn host_set_invisible_borders(invisible_borders: i32); fn host_set_invisible_borders(invisible_borders: i32);
fn host_get_plugin_ids(); fn host_get_plugin_ids();

View file

@ -1,6 +1,6 @@
[package] [package]
name = "zellij-utils" name = "zellij-utils"
version = "0.13.0" version = "0.14.0"
authors = ["Kunal Mohan <kunalmohan99@gmail.com>"] authors = ["Kunal Mohan <kunalmohan99@gmail.com>"]
edition = "2018" edition = "2018"
description = "A utility library for Zellij client and server" description = "A utility library for Zellij client and server"
@ -27,7 +27,7 @@ structopt = "0.3"
strum = "0.20.0" strum = "0.20.0"
termion = "1.5.0" termion = "1.5.0"
vte = "0.10.1" vte = "0.10.1"
zellij-tile = { path = "../zellij-tile/", version = "0.13.0" } zellij-tile = { path = "../zellij-tile/", version = "0.14.0" }
[dependencies.async-std] [dependencies.async-std]
version = "1.3.0" version = "1.3.0"

View file

@ -207,7 +207,8 @@ pub enum ScreenContext {
ToggleActiveTerminalFullscreen, ToggleActiveTerminalFullscreen,
SetSelectable, SetSelectable,
SetInvisibleBorders, SetInvisibleBorders,
SetMaxHeight, SetFixedHeight,
SetFixedWidth,
ClosePane, ClosePane,
ApplyLayout, ApplyLayout,
NewTab, NewTab,

View file

@ -110,31 +110,27 @@ fn split_space_to_parts_vertically(
let mut split_parts = Vec::new(); let mut split_parts = Vec::new();
let mut current_x_position = space_to_split.x; let mut current_x_position = space_to_split.x;
let mut current_width = 0; let mut current_width = 0;
let max_width = space_to_split.columns - (sizes.len() - 1); // minus space for gaps let max_width = space_to_split.cols - (sizes.len() - 1); // minus space for gaps
let mut parts_to_grow = Vec::new(); let mut parts_to_grow = Vec::new();
// First fit in the parameterized sizes // First fit in the parameterized sizes
for size in sizes { for size in sizes {
let (columns, max_columns) = match size { let columns = match size {
Some(SplitSize::Percent(percent)) => { Some(SplitSize::Percent(percent)) => {
((max_width as f32 * (percent as f32 / 100.0)) as usize, None) (max_width as f32 * (percent as f32 / 100.0)) as usize
} // TODO: round properly } // TODO: round properly
Some(SplitSize::Fixed(size)) => (size as usize, Some(size as usize)), Some(SplitSize::Fixed(size)) => size as usize,
None => { None => {
parts_to_grow.push(current_x_position); parts_to_grow.push(current_x_position);
( 1 // This is grown later on
1, // This is grown later on
None,
)
} }
}; };
split_parts.push(PositionAndSize { split_parts.push(PositionAndSize {
x: current_x_position, x: current_x_position,
y: space_to_split.y, y: space_to_split.y,
columns, cols: columns,
rows: space_to_split.rows, rows: space_to_split.rows,
max_columns,
..Default::default() ..Default::default()
}); });
current_width += columns; current_width += columns;
@ -152,11 +148,11 @@ fn split_space_to_parts_vertically(
for (idx, part) in split_parts.iter_mut().enumerate() { for (idx, part) in split_parts.iter_mut().enumerate() {
part.x = current_x_position; part.x = current_x_position;
if parts_to_grow.contains(&part.x) { if parts_to_grow.contains(&part.x) {
part.columns = new_columns; part.cols = new_columns;
last_flexible_index = idx; last_flexible_index = idx;
} }
current_width += part.columns; current_width += part.cols;
current_x_position += part.columns + 1; // 1 for gap current_x_position += part.cols + 1; // 1 for gap
} }
} }
@ -164,7 +160,7 @@ fn split_space_to_parts_vertically(
// we have some extra space left, let's add it to the last flexible part // we have some extra space left, let's add it to the last flexible part
let extra = max_width - current_width; let extra = max_width - current_width;
let mut last_part = split_parts.get_mut(last_flexible_index).unwrap(); let mut last_part = split_parts.get_mut(last_flexible_index).unwrap();
last_part.columns += extra; last_part.cols += extra;
for part in (&mut split_parts[last_flexible_index + 1..]).iter_mut() { for part in (&mut split_parts[last_flexible_index + 1..]).iter_mut() {
part.x += extra; part.x += extra;
} }
@ -184,26 +180,21 @@ fn split_space_to_parts_horizontally(
let mut parts_to_grow = Vec::new(); let mut parts_to_grow = Vec::new();
for size in sizes { for size in sizes {
let (rows, max_rows) = match size { let rows = match size {
Some(SplitSize::Percent(percent)) => ( Some(SplitSize::Percent(percent)) => {
(max_height as f32 * (percent as f32 / 100.0)) as usize, (max_height as f32 * (percent as f32 / 100.0)) as usize
None, } // TODO: round properly
), // TODO: round properly Some(SplitSize::Fixed(size)) => size as usize,
Some(SplitSize::Fixed(size)) => (size as usize, Some(size as usize)),
None => { None => {
parts_to_grow.push(current_y_position); parts_to_grow.push(current_y_position);
( 1 // This is grown later on
1, // This is grown later on
None,
)
} }
}; };
split_parts.push(PositionAndSize { split_parts.push(PositionAndSize {
x: space_to_split.x, x: space_to_split.x,
y: current_y_position, y: current_y_position,
columns: space_to_split.columns, cols: space_to_split.cols,
rows, rows,
max_rows,
..Default::default() ..Default::default()
}); });
current_height += rows; current_height += rows;

View file

@ -11,6 +11,7 @@ pub struct Options {
/// Allow plugins to use a more simplified layout /// Allow plugins to use a more simplified layout
/// that is compatible with more fonts /// that is compatible with more fonts
#[structopt(long)] #[structopt(long)]
#[serde(default)]
pub simplified_ui: bool, pub simplified_ui: bool,
/// Set the default theme /// Set the default theme
#[structopt(long)] #[structopt(long)]

View file

@ -8,15 +8,18 @@ pub struct PositionAndSize {
pub x: usize, pub x: usize,
pub y: usize, pub y: usize,
pub rows: usize, pub rows: usize,
pub columns: usize, pub cols: usize,
pub max_rows: Option<usize>, // FIXME: Honestly, these shouldn't exist and rows / columns should be enums like:
pub max_columns: Option<usize>, // Dimension::Flex(usize) / Dimension::Fixed(usize), but 400+ compiler errors is more than
// I'm in the mood for right now...
pub rows_fixed: bool,
pub cols_fixed: bool,
} }
impl From<Winsize> for PositionAndSize { impl From<Winsize> for PositionAndSize {
fn from(winsize: Winsize) -> PositionAndSize { fn from(winsize: Winsize) -> PositionAndSize {
PositionAndSize { PositionAndSize {
columns: winsize.ws_col as usize, cols: winsize.ws_col as usize,
rows: winsize.ws_row as usize, rows: winsize.ws_row as usize,
..Default::default() ..Default::default()
} }