Commit graph

51 commits

Author SHA1 Message Date
Aram Drevekenin
27c8986939
feat: multiple Select and Bulk Pane Actions (#4169)
* initial implementation with break panes to new tab

* break pane group left/right

* group embed/eject panes

* stack pane group on resize

* close pane group

* style(fmt): rustfmt

* fix tests

* group drag and ungroup with the mouse

* fix mouse hover for multiple clients

* fix for multiple clients

* multiple select plugin initial

* use real data in plugin

* adjust functionality

* fix some ux issues

* reflect group mouse group selections in plugin

* group/ungroup panes in Zellij

* highlight frames when marked by the plugin

* refactor: render function in plugin

* some ui responsiveness

* some more responsiveness and adjust hover text

* break out functionality

* stack functionality

* break panes left/right and close multiple panes

* fix(tab): only relayout the relevant layout when non-focused pane is closed

* status bar UI

* embed and float panes

* work

* fix some ui/ux issues

* refactor: move stuff around

* some responsiveness and fix search result browsing bug

* change plugin pane title

* differentiate group from focused pane

* add keyboard shortcut

* add ui to compact bar

* make boundary colors appear properly without pane frames

* get plugins to also display their frame color

* make hover shortcuts appear on command panes

* fix: do not render search string component if it's empty

* BeforeClose Event and unhighlight panes on exit

* some UI/UX fixes

* some fixes to the catppuccin-latte theme

* remove ungroup shortcut

* make some ui components opaque

* fix more opaque elements

* fix some issues with stacking pane order

* keyboard shortcuts for grouping

* config to opt out of advanced mouse actions

* make selected + focused frame color distinct

* group marking mode

* refactor: multiple-select plugin

* adjust stacking group behavior

* adjust flashing periods

* render common modifier in group controls

* add to compact bar

* adjust key hint wording

* add key to presets and default config

* some cleanups

* some refactoring

* fix tests

* fix plugin system tests

* tests: group/ungroup/hover

* test: BeforeClose plugin event

* new plugin assets

* style(fmt): rustfmt

* remove warnings

* tests: give plugin more time to load
2025-04-29 20:52:17 +02:00
Aram Drevekenin
f0680fdeb9
fix(clipboard): clipboard message (#4009)
* fix clipboard message

* fix clipboard message gitter

* style(fmt): rustfmt
2025-02-20 17:14:43 +01:00
Mark Grey
26b99eac63
feat(config): new theme definition spec (#3242)
* Implement initial structs from spec

* kdl configuration unmarshalling

* typo text styling

* remove is_selected toggle

* incorporate new status bar ui into theming

* improve test coverage of config behavior

* tab bar correction

* correct also compact bar

* remove spacing between table columns

* refactor table styling

* use text_unselected.emphasis_1 for keygroup sep

* fix tab bar more text

* repair field flattening for theme

* remove extra styling KDL node

* update tests

* updated selected text conversion

* padding for header bar

* minor corrections for existing themes

* background handling

* compact bar corrections

* properly handle opaque method to activate background

* update newer plugins to use styling struct

* correct omission of selected state

* fix: bold typeface for text elements

* fix: fg -> white for list_unselected conversion

* fix: emphasis and opacity handling for nested_list

* correct stylings in the session-manager

* fix emphases translation for table component

* correct emphasis for run instructions

* correct frame_highlight translation for old themes

* provide missing implementation of frame_highlight

* fencepost emphasis color names

* Set a pseudo-None for frame_unselected in old theme conversion

* correct alternating bg for simplified-ui

* update snapshots

* fix inner text padding and errorneous snapshots

* suppress warning about deprecated usage of palette

* remove unused import

* feat(plugins): API to change floating pane coordinates (#3958)

* basic functionality through the cli

* added to plugin api

* add display area and viewport size to TabInfo

* fix tests and add new one

* some cleanups

* refactor: extract pane_id parsing logic

* style(fmt): rustfmt

* docs(changelog): floating pane coordinate chagne API

* fix(tiled-panes): opening panes from the cli (#3963)

* feat(plugins): add `PastedText` Event (#3962)

* working with text paste

* handle utf8 conversion error

* feat(plugins): add PastedText Event

* docs(changelog): plugins pasted text event

* black for table opaque background

* properly apply opacity to table

* correct padding for explicit width ribbons

* feat(plugins): Allow opening panes near plugin (#3966)

* added command + terminal variants

* added editor variant

* style(fmt): rustfmt

* docs(changelog): plugin apis to open panes near plugin

* feat(plugins): send info about $EDITOR and $SHELL (#3971)

* feat(plugins): send info about $EDITOR and $SHELL

* fix(e2e): snapshot update

* docs(changelog): plugin editor and shell info

* fix(floating-panes): when changing coordinates, if a pane is not floating - make it floating (#3972)

* fix(panes): when changing floating pane coordinates, if the pane is not floating, float it

* style(fmt): rustfmt

* docs(changelog): floating pane coordinate fix

* fix(break-pane): strip logical position when inserting pane to new tab (#3973)

* docs(changelog): logical position fix

* Optional frame_unselected theme

* fixture with correct width to account for arrow padding

* update snapshot and rustfmt

---------

Co-authored-by: Aram Drevekenin <aram@poor.dev>
2025-02-07 11:59:54 +01:00
Daniel Jankowski
0cd6d5f4e5
feat(plugins): add configurable black background for ui components (#3681)
* feat(plugins): add transparent background for text and nested_list

* chore: fix formatting issue

* feat: invert flag behaviour

* feat: implement bg_black handling for table cells

* fix: order of selected and bg_black in protocol

* chore: rename from bg_black to opaque

* fix: explicit selected, if opaque and selected for text

* chore: fix formatting issues

* feat: opaque tab-bar

* feat: opaque session-manager bars

* feat: opaque ribbon in plugin manager

* feat: opaque one-line ui

* feat: opaque tab-bar in configuration plugin
2024-10-24 18:21:44 +02:00
Aram Drevekenin
0277c5f6a7
fix(ux): new interface/configuration touch-ups (#3691)
* fix(ui): copy to clipboard in new ui

* fix(ux): allow navigating out of scrolled pane

* style(fmt): rustfmt
2024-10-23 14:37:23 +02:00
Aram Drevekenin
a6d6c0e4ff
feat(ui): status bar redesign (#3475)
* work

* work

* working

* get default mode from server and some ui responsiveness

* work

* finish design and get tests to pass

* get e2e tests to pass

* add classic layout

* add classic layout assets

* fix e2e tests

* style(fmt): rustfmt

* fix plugin system test

* style(fmt): some cleanups
2024-07-05 15:13:51 +02:00
Aram Drevekenin
62c37a87cc
feat(keybindings): support multiple modifiers (eg. Ctrl+Alt) and the kitty keyboard protocol (#3383)
* parse kitty keys from STDIN

* work

* work

* replace internal Key representation with the new KeyWithModifier in all the places

* work

* work

* allow disabling with config

* adjust ordering

* handle enabling/disabling properly on the client

* support multiple modifiers without kitty too

* normalize uppercase keys

* get tests to pass

* various cleanups

* style(fmt): rustfmt
2024-05-27 16:15:09 +02:00
Bradford Hovinen
312817fcf6
fix(config): add support for Ctrl and Alt modifiers on function keys in keybindings (#3179)
Previously, it was not possible to define keybindings with a modifier
and a function key. The `Key` enum only supported combinging the Ctrl
and Alt modifiers with letters. This is somewhat limiting: I would like
to make the Zellij keybindings more "distant" than those used in the
programs I use from within Zelilj, so that Zellij does not intefere with
those programs. Thus I would like to move some of the keybindings from
Ctrl+<character> to Ctrl+<function key>.

This change adds:

  * support for function keys with the Ctrl and Alt modifiers in the
    `Key` enum,
  * support for parsing such keybindings from the configuration file,
  * support for such keybindings in the protobuf which communicates the
    keybindings to plugins, and
  * support for these keybindings in the plugin API.

This is tested by modifying one of the e2e tests to include an example
of such keybindings. This verifies that the configuration is correctly
parsed, communicated with the plugin, and rendered.
2024-03-25 15:04:38 +01:00
Aram Drevekenin
09d09759b5
fix(ux): various ui/ux fixes (#2722)
* force plugin render on permission request response

* clear warnings

* Revert "feat(ui): new status bar mode (#2619)"

This reverts commit 27763d26ab.

* adjust status bar help

* fix colors in session manager and shortcut in status-bar

* adjust keybindings
2023-08-24 18:11:53 +02:00
Aram Drevekenin
c95d0e769f
feat(plugins): make plugins configurable (#2646)
* work

* make every plugin entry point configurable

* make integration tests pass

* make e2e tests pass

* add test for plugin configuration

* add test snapshot

* add plugin config parsing test

* cleanups

* style(fmt): rustfmt

* style(comment): remove commented code
2023-07-25 10:04:12 +02:00
Aram Drevekenin
27763d26ab
feat(ui): new status bar mode (#2619)
* supermode prototype

* fix integration tests

* fix tests

* style(fmt): rustfmt
2023-07-12 11:31:00 +02:00
Aram Drevekenin
f1ff272b0b
feat(ui): swap layouts and stacked panes (#2167)
* relayout working with hard coded layout

* work

* refactor(layout): PaneLayout => TiledPaneLayout

* tests passing

* tests passing

* tests passing

* stacked panes and passing tests

* tests for stacked panes

* refactor(panes): stacked panes

* fix: focusing into stacked panes from the left/right

* fix(layouts): handle stacked layouts in the middle of the screen

* fix(pane-stack): focus correctly when coming to stack from above/below

* fix(stacked-panes): resize stack

* fix(stacked-panes): focus with mouse

* fix(stacked-panes): focus next pane

* fix(layout-applier): sane focus order

* fix(stacked-panes): better titles for one-liners

* fix(stacked-panes): handle moving pane location in stack

* fix(relayout): properly calculate display area

* fix(relayout): properly calculate rounding errors

* fix(stacked-panes): properly handle closing a pane near a stack

* fix(swap-layouts): adjust swap layout sort order

* feat(swap-layouts): ui + ux

* fix(swap-layouts): include base layout

* refactor(layout): remove unused method

* fix(swap-layouts): respect pane contents and focus

* work

* fix(swap-layouts): load swap layouts from external file

* fix(swap-layouts): properly truncate layout children

* fix(stacked-panes): allow stacked panes to become fullscreen

* fix(swap-layouts): work with multiple tabs

* fix(swap-layouts): embed/eject panes properly with auto-layout

* fix(stacked-panes): close last pane in stack

* fix(stacked-panes): move focus for all clients in stack

* fix(floating-panes): set layout damaged when moving panes

* fix(relayout): move out of unfitting layout when resizing whole tab

* fix(ui): background color for swap layout indicator

* fix(keybinds): add switch next layout in tmux

* fix(ui): swap layout indication in compact layout

* fix(compact): correct swap constraint

* fix(tests): tmux swap config shortcut

* fix(resizes): cache resizes so as not to confuse panes (eg. vim) with multiple resizes that it debounces weirdly

* feat(cli): dump swap layouts

* fix(ui): stacked panes without pane frames

* fix(ux): move pane forward/backwards also with floating panes

* refactor(lint): remove unused stuff

* refactor(tab): move swap layouts to separate file

* style(fmt): rustfmt

* style(fmt): rustfmt

* refactor(panes): various cleanups

* chore(deps): upgrade termwiz to get alt left-bracket

* fix(assets): merge conflicts of binary files

* style(fmt): rustfmt

* style(clippy): no thank you!

* chore(repo): remove garbage file
2023-02-17 12:05:50 +01:00
Jae-Heon Ji
00cd33637b
feat: add args to new-tab action (#2072)
* fix(themes): missing tokyo-night-dark theme

* feat: add args to new-tab action

* fix: name can be set without layout

* feat: pass config options to action parser

* chore: remove unnecessary default values

* chore: update snapshots

* fix(status-bar): add exception for NewTab

* fix: update code review

* feat: add shallow_eq for action
2023-02-16 22:32:27 +09:00
Felix Pankratz
a369e70d94
fix(status-bar): not displaying w/ size=1 and show shortcuts (#2091)
* Fix status bar not displaying if size=1. Show shortcuts if not in normal mode when size=1

* formatting

Co-authored-by: Felix Pankratz <mail@felixpankratz.de>
2023-01-27 13:37:18 +01:00
har7an
62eaea1583
Reimplement resize code (#1990)
* server/floating_panes: Start removing `unwrap`s

* server/panes: Remove more `unwrap`s

in floating panes code.

* utils/data: Unify `Direction` type

which was previously present in multiple locations.
Also start working on a new Resize Method (type `ResizeStrategy`), to
remove code duplication in the resize code.

* server: Implement new resize handling

with the `ResizeStrategy` type. Add a new action with the ability to
invoke it from the CLI. Take care to maintain backwards-compatibility in
terms of configuring the new resize mode.

* utils/layout: Add conversion for SplitDirection

from `data::Direction`.

* utils/data: Add impl for `Direction`

* server/panes: Rework tiled pane resizing

but it's currently still broken in a few regards and misses ability to
perform "regular" increase/decrease.

* server/panes/tiled_panes: Add debug assertion

to catch if the total area of all panes (in percent) is different from
100.0 at some point.

* server/panes/tiled/grid: Fix resize bug

caused by the fact that neighboring plugin panes previously weren't
filtered from resize operations, even though they cannot be resized at
all.

* utils/data: Add `invert` for `Resize`

* utils/data: Add member to `ResizeStrategy`

that controls whether we invert resize behavior when increasing size
towards a bounadry. This maintains current behavior.

* server/screen: Handle new attribute

in `ResizeStrategy`

* server/panes/resizer: Return `anyhow::Error`

* server/panes/tiled: Implement resize increase/decrease

without specifying a direction (towards all possible directions).
Currently broken in some cases.

* server/pane/tiled/grid: Don't return early

to preserve resize debug assertions.

* server/pane/tiled/grid: Fix resize bug

caused by checking for the wrong alignments in some cases. Also refactor
the code for looking up aligned panes.

* server/panes/tiled/grid: Cleanup code

and remove log statements and unused functions.

* server/panes/float/grid: Invert resize

if the floating pane is hitting a boundary already.

* plugins/status-bar: Add hints for new resize

* server: Use new resize method

* server: Fix tests

with new functions and result types.

* apply rustfmt

* utils: Apply rustfmt

* server/panes/floating: Fix resize increase

behavior which would previously, upon hitting a boundary, cause the pane
to invert the resize operation, which is wrong. Instead, it now does not
resize floating panes on an undirected resize "increase" in directions
where it hits boundaries.

* server/panes/tiled: Use correct resize increments

The values for the resize increments were previously wrong, causing many
of the tests to fail.

* server/panes/tiled: Fix resize checks

to correctly consider fixed-size panes.

* utils/assets/config: Update default config

with new keybindings for resize mode.

* server/panes/tiled: Fix resize check

* server/panes/tiled: Use shortener for `Direction`

type in `change_pane_size` function.

* server/panes/tiled: Restore resize behavior

for undirected resizes, to the way it was before this PR.

* server/panes/floating: Fix resize increment

for undirected resizes

* utils/data: Fix doctest

* utils: Fix test snapshots

for tests working with the default config

* changelog: Add PR #1990
2022-12-08 12:50:28 +00:00
Aram Drevekenin
63e7531c48
performance(rendering): improve rendering performance (#1960)
* refactor(plugins): plugins now need to explicitly ask to be rendered

* performance(render): remove various needless renders

* performance(render): cache boundaries

* performance(render): adjust tests and cache cursor location/shape

* style(comment): remove outdated

* style(fmt): rustfmt
2022-11-21 20:07:24 +01:00
Aram Drevekenin
3d2a6d6a5a
refactor(plugins): change the data flow (#1934)
* refactor(plugins): do not block render loop

* refactor(plugins): cleanup

* style(fmt): rustfmt

* fix(plugins): various rendering pipeline fixes
2022-11-15 12:21:36 +01:00
Mathieu Santostefano
86e765ea4d
fix(status-bar): display controls line of status-bar plugin if pane size=1 (#1875) 2022-10-31 19:40:27 +01:00
har7an
f76b828209
fix(status-bar): reflect actual current keybindings (#1242)
* status-bar: first_line: Use more generic var names

Rename all `CtrlKey...` to the equivalent `Key...` to make the name less
specific. It implies that all key bindings use Ctrl as modifier key,
which needn't necessarily be the case.

* status-bar: first_line: Refactor `ctrl_keys`

Removes lots of code duplication by `Unselect`ing all keys by default
and only `Select`ing what is actually required for a given Input mode.

* utils: conditionally compile unix-specific code

In `zellij_utils`, the following modules each contained code that was
previously targeting only the unix platform:

- consts: Works with unix-specific filesystem attributes to set e.g.
  special file permissions. Also relies on having a UID.
- shared: Uses unix-specific filesystem attributes to set file
  permissions

These will never work when targeting wasm. Hence the concerning code
passages have been moved into private submodules that are only compiled
and re-exported when the target isn't `#[cfg(unix)]`. The re-export
makes sure that crates from the outside that use `zellij_utils` work as
before, since from their point of view nothing has changed.

* utils: Share more modules with wasm

that work on both wasm and unix natively. This requires factoring out
bits of code in the `setup` and `input` modules into a private submodule
that is re-exported when the compilation target is *not* "wasm". The
following modules are now available to the wasm target:

- cli
- consts
- data
- envs
- input (partial)
    - actions
    - command
    - configs
    - keybinds
    - layout
    - options
    - plugins
    - theme
- pane_size
- position
- setup (partial)
- shared

The remaining modules unavailable to wasm have dependencies on crates
that cannot compile against wasm, such as `async_std` or `termwiz`.

* utils/input/keybinds_test: Fix import

of the `CharOrArrow` struct which is now part of the `data` submodule.

* utils/layout: Use global serde crate

Previously the code was decorated with `#[serde(crate = "self::serde")]`
statements which cannot be shared with wasm. Use the regular serde
without specifying which serde is meant.

* utils/data: Implement `fmt::Display` for `Key`

so the Keybindings can be displayed via `format!` and friends in e.g.
the status bar.

* tile/prelude: Re-export `actions`

submodule of `zellij_utils` so the plugins can access the `ModeKeybinds`
struct with all of its members.

* utils/data: Fix `ModeInfo::keybinds` type

and transfer a vector of `(Key, Vec<Action>)` to the plugins so they can
parse it themselves, instead of passing strings around. Due to the
requirement of the `Eq` trait derive on `ModeInfo` this requires
deriving `Eq` on all the types included by `Key` and `Action` as well.

Note that `Action` includes the `layout::SplitSize` structure as a
member. We cannot derive `Eq` here since `SplitSize::Percent(f64)`
cannot satisfy `Eq` because `f64` doesn't implement this. So we add a
new type to hack around this limitation by storing the percentage as
`u64` internally, scaled by a factor of 10 000 and transforming it to
f64 when needed. Refer to the documentation of `layout::Percent` for
further information.

* utils/data: Make `Key` sortable

so the keybindings can be sorted after their keys.

* WIP: utils/input: Make keybinds accessible

when generating `ModeInfo` structs.

* utils/data: Handle unprintable chars in `Key`

when displaying via the `fmt::Display` trait. Handles `\t` and `\n` and
represents them as UTF-8 arrow glyphs.

* HACK: utils/layout: Use u64 for SplitSize::Percent

The previous workaround using a custom `Percent` type fails at the
absolute latest when confronted with user layouts, since these do not
know about the scaling factor and will thus break. It still breaks
currently because `Percent` now expects a u64 (i.e. `50`, not `50.0`)
but this is more easily explained and understood.

* status-bar: Add helper macros

that retrieve the key bound to execute a sequence of `Action` given a
specific Keybinding, and a shorthand that expands to
`Action::SwitchToMode(InputMode::Normal)` used for pattern matching with
the `matches!` macro.

* status-bar/first_line: Get shared superkey if any

from the `ModeKeybindings` in the current `ModeInfo` struct. If the
configured keybindings for switching the modes don't have a superkey in
common, do not print a common prefix.

* status-bar/first_line: Add key to KeyShortcut

which is the key that must be pressed in the current mode to execute the
given shortcut (i.e. switch to the given mode).

* status-bar/first_line: Dynamically set mode binds

Read the keybindings for switching the modes to print in the first line
from the actually configured keybindings for the current mode. Add some
logic to the code that:

- Prints only the "single letter" of the keybinding if all mode-switch
  shortcuts *share the same modifier key*,
- Or prints the whole keybinding (with modified) into each segment if
  there is no common modifier key.

* status-bar/second_line: Display configured binds

Instead of showing some hard-coded default values. For each mode, reads
the keybindings from the configured keybindings based on some sequence
of action. For example, the keybinding for `New` in the `Pane` menu is
now determined by looking into the configured keybindings and finding
what key is bound to the `Action::NewPane(None)` action.

If no keybinding is found for a given sequence of actions, it will not
show up in the segments either.

* WIP: utils/keybinds: Make key order deterministic

by using a BTreeMap which by default has all of its elements in sorted
order internally. As of currently this doesn't seem to impress the order
in which the keybindings are sent to the plugins, though.

* utils/data: Reorder `Key` variants

to have the Arrow keys sorted as "left", "down", "up", "right" in
accordance with the display in e.g. the status bar.

* status-bar/first_line: Fix inverted `matches!`

when trying to obtain the keybindings to switch between the input modes.
Its initial purpose was to filter out all ' ', '\n' and 'Esc'
keybindings for switching modes (As these are the default and not of
interest for the status bar display), but it was not negated and thus
only filtered out the aforementioned keys.

* status-bar: Don't get all modeswitch keybinds

but only those that are displayed in the status bar. This currently
excludes the keybindings for Entering the Pane/TabRename mode, Tmux mode
and Prompt mode. We must explicitly exclude these since they aren't
bound to the same Modifiers as the regular keys. Thus, if we e.g. enter
Pane or Tab mode, it will pick up the
`SwitchToMode(InputMode::TabRename)` action as being bound to `c`, hence
the `superkey` function cannot find a common modifier, etc. But we don't
display the `TabRename` input mode in the first line anyway, so we must
ignore it.

Therefore, we additionally add the keybinding to call the `Action::Quit`
action to terminate zellij to the vector we return. Also remove the
`(Key, InputMode)` tuple and convert the return type to a plain
`Vec<Key>`, since the never worked with the `InputMode` in the first
place.

* status-bar/first_line: Fix output for tight screen

Implement the "Squeezed" display variant where we do not display which
of the modes each keybinding switches to, but only the keybinding
itself.

* status-bar/second_line: Remove trailing " / "

* status-bar/second-line: Refactor key hints

Instead of determining the appropriate key hints for every case
separately (i.e. enough space to show all, show shortened, shot
best-effort), create a central function that returns for the current
`InputMode` a Vector with tuples of:

- A String to show in full-length mode
- A String to show in shortened/best-effort mode
- The vector of keys that goes with this key hint

This allows all functions that need the hints to iterate over the vector
and pick whatever hint suits them along with the Keys to display.

* status-bar/second-line: Implement shortened hints

* utils/data: Fix display for `Key::Alt`

which previously printed only the internal char but not the modifier.

* status-bar/first-line: Add hidden Tmux tile

that is only shown when in Tmux mode. Note that with the default config
this "breaks" the shared superkey display, because it correctly
identifies that one can switch to Scroll mode via `[`.

* status-bar: Print superkey as part of first line

Instead of first obtaining the superkey and then the rest of the first
line to display. This way we don't need to split up individual data
structures and carry a boolean flag around multiple functions.

It also has the advantage that when the available space is really tight,
the first line is entirely empty and doesn't display a stale superkey
without any other keybinding hints.

* status-bar: Rework keybinding theming

Previously there were individual functions to create the tiles in the
first line depending on whether:

- A tile was selected, unselected, unselected alternate (for theming) or disabled, and
- Tiles had full length or were displayed shortened

In the first case, the functions that previously handled the theming
only differed in what theme they apply to the otherwise identical
content. Since the theming information was drawn from a flat structure
that simulated hierarchy by giving hierarchical names to its theme
"members", this couldn't be handled in code. In the second case, some of
the theming information needed for the full-length shortcuts was
replicated for the shortened shortcuts.

Instead, rewrite the general Theming structure into a hierarchical one:
Adds a new structure `SegmentStyle` that contains the style for a single
segment depending on whether it is selected, unselected (alternate) or
disabled. Refactor the `first-line` module to use a single function to
generate either full-length or shortened tiles, that does functionally
the same but switches themes based on the selection status of the tile
it themes.

* status-bar/second-line: Return new `LinePart`s

from the `add_shortcut` function instead of modifying the input
parameters.

* status-bar/second-line: Implement adaptive behavior

and make the keyhints adapt when the screen runs out of space. The hints
first become shortened and when necessary partially disappear to display
a "..." hint instead.

* status-bar/second-line: Show float pane binding

based on the keycombination that's really bound to switching into the
"Pane" input mode.

* status-bar/get_keys_and_hints: Add more modes

for the keybindings in Tmux and the Pane/TabRename input modes.

* status-bar/second-line: Unify mode handling

and don't do extra shortcut handling for Tmux and the Pane/TabRename
modes any longer. Instead, assemble this like for all other modes from
the keybinding and hints vector.

* status-bar/first-line: Refactor common modifier

to a separate function so it can be used by other modules, too.

* status-bar/second-line: Display modifier in hints

when available. For example, for bindings to move between panes when in
PaneRename mode, now displays "Alt + <hjkl>" instead of
"<Alt+hAlt+j...>".

* utils/ipc: Remove `Copy` from `ClientAttributes`

 as preparation to add `Keybinds` as a member to the `ClientAttributes`
 struct. `Keybinds` contains a `HashMap`, for which the `std` doesn't
 derive `Copy` but only `Clone`.

* utils/input/keybinds: Fix import path

Import `Key` and `InputMode` directly from `data`.

* utils/ipc: Add `Keybinds` to `ClientAttributes`

so we can keep track, pre-client, of the configured key bindings and
pass them around further in the code.

* server/lib: Store `ClientAttributes` over `Style`

in `SessionMetadata` to be able to pass Keybindings to other places in
the code, too. Since `Style` is also a member of `ClientAttributes`,
this works with minimal modifications.

* utils/input: Change `get_mode_info` parameters

to take a `ClientAttributes` struct instead of merely the `Style`
information. This way we can get the `Style` from the
`ClientAttributes`, and also have access to the `keybinds` member that
stores the keybinding configuration.

* utils/ipc: Use `rmp` for serde of IPC messages

instead of `bincode`, which seemingly has issues (de)serializing
`HashMap`s and `BTreeMap`s since `deserialize_any` isn't implemented for
these types.

* fix(nix): remove `assets` from `gitignore`

Remove `assets` from the gitignore of the plugins themselves,
since every single plugin now depends on the asset being accessible
in its source directory.

* tests/e2e: Fix status bar in snapshots

to reflect the current state of the dynamic keybindings.

* status_bar/first_line: Don't show unbound modes

If switching to a specific mode isn't bound to a key, don't show a
tile/ribbon for it either. E.g. in `LOCKED` mode, this will only show
the tile for the `LOCK` mode and ignore all others.

* utils/data: Make 'Key::Char(' ') visible as "␣"

so the user doesn't only see a blank char but has an idea that the space
key is meant.

* status_bar/second_line: Remove extra hints

generated by the `hint_producing_function` that would tell the user in
every input mode how to get back to normal mode. Instead, add this as
keybinding to the general keybindings vector.

This removes some lines of duplicated code but most of all now applies
the correct theming to this keybinding. Additionally, previously the
`RenameTab` and `RenamePane` input modes would show the keybinding to
get back to normal mode twice and both of them were hardcoded. This
binding is now dynamically displayed based on what the user configured
as keybinding.

* utils/data: format unprintable chars as words

instead of unicode symbols. E.g. write "SPACE" instead of "␣".

* utils/data: Fix display for `Ctrl`/`Alt` keys

previously their "inner" chars would be displayed with a regular
`fmt::Display` for the `&str` type they are. This doesn't match what we
want to output. So instead we wrap the inner chars into `Key::Char`
before printing them.

* utils/data: Change order of `Key`s

so that e.g. for the default bindings in `Scroll` mode we prefer to show
`PgDn|PgUp` rather than the arrow keys these actions are bound to as
well.

* status_bar/first_line: Don't ignore default char

bindings by default. These include the '\n', ' ' and 'Esc' bindings that
by default lead back to `Normal` input mode from all the modes.
Previously we would unconditionally ignore them and consequently not
print the tile when in fact the user may have bound this particular
action to either of the keys.

Instead now we first ignore the keys mentioned and if we turn up with an
undefined binding, we consider these default keys as well so we get
*something* to display in any case.

* status_bar/first_line: Add space when no modifier

is shared between the keybindings. This way there isn't a stray arrow at
the very border of the screen, but it is spaced just like the tab-bar
and the second line is.

* status_bar/second_line: Print separators

between consecutive keys bound to specific actions. This allows the user
to visually differ between different keys.

* status_bar/main: Don't return modifier if empty

* status_bar/first_line: Don't suppress Disabled tiles

Disabled is a special state that the keybindings only assume in locked
mode. It turns the respective tiles grey to signal to the user that
these are currently inactive. With respect to users new to zellij, it
may appear confusing that when entering locked mode all the other tiles
disappear (which they do because they have no valid keybinding
assigned). Since we have no keybinding for them, we still display them
but without any associated key (i.e. as `<>` for the binding).

* status_bar/first_line: Don't print leading triangle

on first tile, when there is no shared superkey.

* status_bar/second_line: Add exceptions

for inter-key separators. Keeps groups of `hjkl` and arrow keys intact
(doesn't add separators between the keys) but separates all others.

* status_bar/main: Refactor `action_key`

to a regular function instead of a macro. It turns out that while being
able to match patterns is a nice feature, we completely rely on the keys
that drop out of the pattern found this way to be sorted in a sensible
way. Since we sort the key vectors in the necessary places after the
keys, and not the actions, this of course doesn't apply when the user
changes "hjkl" to "zjkl", which would then become "jklz". Now this is of
course wrong, because "z" still means "Move focus left", and not "Move
focus right".

With the function we now assume a slice of Actions that we match the
action vectors from the keybindings against to obtain the necessary
keys. In order to avoid ugly `into_iter().chain(...)` constructs we had
before we also add a new function `action_key_group` that takes a sliced
array of slices to get a whole group of keys to display.

* status_bar/first_line: Fix "triangle" for short tiles

since we do not want to display a colored triangle at the start of the
line when in sortened mode (just as we do for the long tiles now).
Also fix a bug that would make the triangle reappear when the first
keybinding to be displayed didn't have a key assigned and thus wouldn't
be displayed at all.

* status_bar/second_line: Fix typo

that would cause single `Ctrl+?` bindings for actions in the second line
to be displayed as `Ctrl + <Ctrl+?>`.

* status_bar/second_line: Fix char count

when displaying groups of keys in a binding with or without a separator.

* status_bar: Use new `action_key` fn

instead of the previous macro to obtain the keys to display in the
status bar in a fixed given order. Also fix the display "bug" where tab
switching would be shows as "ArrowLeft/ArrowDown" instead of
"ArrowLeft/ArrowRight".

* status_bar/second_line: Fix floating pane hint

that tells the user what keybinding to press to suppress the currently
active floating panes. This was previously hardcoded.

* utils: Send full keybinds in `ModeInfo`

instead of the currently active `ModeKeybinds` for the active input
mode. Some of the UI issues cannot be solved without having access to
*all* keybindings.

* utils: Refactor keybinds vec into type

to make clippy happy.

* status_bar/first_line: Remove needless borrows

* status_bar: Factor out printing keybindings

into a separate function that takes a vector of keys and a palette and
returns the painted key groups, with correct inter-character separation
where necessary and factoring out common modifier keys.

* status_bar/tip: Use real keybindings

instead of printing hard-coded messages to the user.

* status_bar: abort early when keyvector is empty

in `style_key_with_modifier`.

* status_bar/tip: Fix all keybindings

and make them dynamic given the keybindings really active in the current
session. Also display **UNBOUND** is some keybinding is missing from the
users config.

* status_bar: Go clippy!

* status_bar: Add documentation

and add a new exception group to `action_key_group` that ensures that
`hl` and `jk` won't be separated with `|`.

* status_bar/tip: Detect when key aren't bound

correctly and show "UNBOUND" as keyhint instead, then. Previously we
would only check the length of the whole keybinding segment, but that
isn't a good indicator since most of the bindings require changing modes
first, which already adds a variable number of letters to the segment.
However, there is not point in showing how to get to a certain mode, if
the binding needed in that mode doesn't exist.

* status_bar/first_line: Show bindings when locked

if the user has any configured.

* status_bar: Don't consider 'hl', 'jk' groups

that don't need a separator in between the letters.

* status_bar/second_line: Add "search" keybindings

for the new Search functionality.

* tests/e2e: Fix snapshots

with what the status bar now really displays.

* status_bar: Remove old comments

* status_bar/first_line: Rename 'long_tile'

to the more descriptive name 'mode_shortcut', which better describes
what this function does.

* status_bar/first_line: Fix spacing in simple UI

where the modifier would be shows as `Ctrl +`, without a trailing space.
This isn't an issue in regular mode, where we have the spacing from the
arrow gaps (`>>`) that "simulates" this effect.

* status_bar: Refactor  and rename `ctrl_keys`

so it doesn't rely on some "external" index for operation any more.

* status_bar: Add unit tests to shared functions

and fix a bug in the process where certain `Ctrl` keybindings would be
displayed wrong.

* status_bar/first_line: Rename functions

responsible for printing the long and short shortcut keyhint tiles. Also
add some documentation that explains their purpose and the arguments
they accept.

* status_bar/tips: Remove stray "/" in quicknav tip

* utils/layout: Remove old comments

introduced when rewriting `SplitSize::Percent` to not hold an `f64`
type.

* status_bar: Add "regex" as test dependency

We use regular expressions to strip all ANSI escape sequences in the
strings that are produced by the plugin functions during testing. We do
not test for the style information, but merely for the raw text.

* status_bar: Implement unit tests

* Makefile: Always run tests on host triple

This allows the unit tests for all plugins to be run on the host as well
(because their default compilation target is wasm32-wasi).

* tests/e2e: Add test for custom bindings

in the status bar. Makes sure that the modified bindings from a custom
configuration file are read and applied to the UI.

Co-authored-by: a-kenji <aks.kenji@protonmail.com>
2022-07-27 16:48:35 +02:00
a-kenji
67d2673cae
add(style): add trailing comma in match blocks (#1483)
This makes it easier to distinguish from normal blocks
2022-06-10 20:03:13 +02:00
Aram Drevekenin
3be718371a
feat(ui): add status bar tips (#1462)
* feat(ui): add more tips to status bar

* fix(e2e): clear status-bar-tips cache for each test

* style(fmt): rustfmt
2022-06-07 14:28:39 +02:00
Aram Drevekenin
4a8d72d7b9
feat(ui): tweak simplified UI (#1458)
* fix(ui): tweak simplified-ui tabs

* fix(ui): tweak simplified-ui status bar

* style(fmt): rustfmt
2022-06-06 22:32:14 +02:00
Aram Drevekenin
4f13307828 fix(ui): adjust default colors 2022-04-13 15:23:42 +02:00
Kunal Mohan
9f716487ca
Improve theme usage + add default ones (#1274)
* Remove gray from theme config and improve colors for dark themes

* improve theme usage

* Add new themes and minor fixes

* improve tokyo-night theme according to new changes

* Fix formatting

* change default black colour

* docs(CHANGELOG): #1274 improve themes
2022-04-02 03:19:42 +05:30
Brooks Rady
9bfafde123
feat(ui): round frame corners (#1227)
* feat(ui): round frame corners

* Allow rounded_corners to be set without a palette

* Revert "Allow rounded_corners to be set without a palette"

This reverts commit 9271a4b5452f2e59e0ebd55136343f0fbfabaa13.

* fix(style): remove redundant code

* fix(style): clippy lints that somehow got missed

* feat(config): add ui config section
2022-03-22 14:58:16 +00:00
Aram Drevekenin
9fa94970cc
fix(ui): floating panes UI (#1074)
* basic ui

* update plugins

* rustfmt
2022-02-21 18:01:35 +01:00
Thomas Linford
18709acde9
feat(copy): allow osc52 copy destination configuration (#1022)
add copy_cliboard  option to allow configuring copy destination to primary selection instead of default clipboard
2022-02-02 15:22:34 +01:00
Christophe Verbinnen
9cc2645db0
Add a copy command option (#996)
Usage: zellij options --copy-command "xclip -sel clip"

Co-authored-by: Christophe Verbinnen <christophev@knowbe4.com>
2022-01-15 12:38:45 +01:00
Jae-Heon Ji
d79060f69a
feat(status-bar): add multiple tips (#848)
* feat(status-bar): add draft for multiple tips

* feat: add TIPS_MAP

* Simplified 'tip' function.

* chore: update file structure

* feat(status-bar): update method of Tip rendering

* feat(status-bar): change type of tip in State

* refactor(status-bar): related to random tip selection

* feat(status-bar): add simple local cache for testing

* feat(status-bar): add cache system for tip data

* Add mpadir to wasm for plugin to access zellij temp folder.

* refactor(status-bar): update cache and utils

* fix(status-bar): update file read error

* refactor(status-bar): update macros

* chore(status-bar): delete test data

* chore(status-bar): update missing fixes

* feat(status-bar): add detailed error

* style: make clippy
2021-12-09 18:53:46 +01:00
Marcin Puc
56e85f87d6
fix(style): various internal refactorings 2021-12-07 10:24:42 +00:00
Aram Drevekenin
6c6a4393f4
This adds a UI for multiple users in panes (behind a feature flag) (#897)
* feat(ui): multiple users in panes

* style(fmt): make rustfmt happy

* style(fmt): make clippy happy
2021-11-25 16:21:59 +01:00
Kaito Akita
4632e90b73
feat(ui): The status bar indicates that the panes are full screen and how many hidden panes are (#450)
* fix(ui): offset content after viewport construction

* Added the feature to display fullscreen information on the second line of the status-bar.

* fix(strider): update host mount-point

* fix(plugin): create missing data directories as needed

* feat(layout): specify only tab name in `tabs` section (#722)

Allow specifying only the tab name in the `tabs` section

- For example this is now possible:
```
tabs:
  - name: first
    parts:
      - direction: Vertical
      - direction: Vertical
  - name: second
  - name: third
```
  For that the tab section defaults the direction to
  `direction::Horizontal`

- Adds an error upon specifying a tab name inside the `parts` section
  of the tab-layout

* docs(changelog): Solely name tab in `tabs` section

* feature(release): Copy default config to the examples folder on release (#736)

fixes #733

* docs(changelog): Copy example config on release

* Update default config (#737)

* feat(plugin): add manifest to allow for plugin configuration (#660)

* feat(plugins-manifest): Add a plugins manifest to allow for more configuration of plugins

* refactor(plugins-manifest): Better storage of plugin metadata in wasm_vm

* fix(plugins-manifest): Inherit permissions from run configuration

* refactor(plugins-manifest): Rename things for more clarity

- The Plugins/Plugin structs had "Config" appended to them to clarify
  that they're metadata about plugins, and not the plugins themselves.

- The PluginType::OncePerPane variant was renamed to be just
  PluginType::Pane, and the documentation clarified to explain what it
  is.

- The "service" nomenclature was completely removed in favor of
  "headless".

* refactor(plugins-manifest): Move security warning into start plugin

* refactor(plugins-manifest): Remove hack in favor of standard method

* refactor(plugins-manifest): Change display of plugin location

The only time that a plugin location is displayed in Zellij is the
border of the pane. Having `zellij:strider` display instead of just
`strider` was a little annoying, so we're stripping out the scheme
information from a locations display.

* refactor(plugins-manifest): Add a little more documentation

* fix(plugins-manifest): Formatting

Co-authored-by: Jesse Tuchsen <not@disclosing>

* chore(docs): update changelog

* feat(sessions): mirrored sessions (#740)

* feat(sessions): mirrored sessions

* fix(tests): input units

* style(fmt): make rustfmt happy

* fix(tests): make mirrored sessions e2e test more robust

* refactor(sessions): remove force attach

* style(fmt): rustfmtify

* docs(changelog): update change

* fix(e2e): retry on all errors

Co-authored-by: Brooks J Rady <b.j.rady@gmail.com>
Co-authored-by: a-kenji <aks.kenji@protonmail.com>
Co-authored-by: spacemaison <tuchsen@protonmail.com>
Co-authored-by: Jesse Tuchsen <not@disclosing>
Co-authored-by: Aram Drevekenin <aram@poor.dev>
2021-09-27 12:07:28 +02:00
Brooks Rady
76a5bc8a05
feat(ui): overhauled resize and layout systems
* refactor(panes): move to parametric pane sizes

* Fixed the simpler errors by casting to usize

* The least I can do is pass the formatting check...

* Move to stable toolchain

* Well, it compiles?

* And now it doesn't! ;)

* Baseline functionality with the new Dimension type

* Working POC for percent-based resizing

* REVERT THIS COMMIT – DELETES TESTS

* Perfected the discrete resize algorithm

* Fixed fixed-size panes

* Basic bidirectional resize

* feat(resize): finalised parametric resize algorithm

* Reduce the logging level a bit

* Fixed nested layouts using percents

* Bug squishing for implicit sizing

* Here is a funky (read: rubbish) rounding approach

* And now it's gone again!

* Improve discretisation algorithm to fix rounding errors

* Fix the last layout bug (maybe?)

* Mixed explicit and implied percents work now

* Let's pretend that didn't happen...

* Make things a bit less crashy

* Crash slightly more for now (to find bugs)

* Manaually splitting of panes works now

* Start moving to percent-based resizes

* Everything but fullscreen seems to be working

* Fix compilatation errors

* Culled a massive amount of border code

* Why not pause to please rustfmt?

* Turns out I was still missing a few tests...

* Bringing back even more tests!

* Fix tests and pane boarders

* Fix the resize system without gaps

* Fix content offset

* Fixed a bug with pane closing

* Add a hack to fix setting of the viewport

* Fix toggling between shared borders and frames

* fix(tests): make e2e properly use PaneGeom

* style(fmt): make rustfmt happy

* Revert unintentional rounding of borders

* Purge some old borderless stuff

* Fix busted tab-bar shrinking

* Update E2E tests

* Finish implementing fullscreen!

* Don't crash anymore?

* Fix (almost) all tests

* Fix a lack of tab-stops

* All tests passing

* I really can't be bothered to debug a CI issue

* Tie up loose ends

* Knock out some lingering FIXMEs

* Continue to clean things up

* Change some naming and address FIXMEs

* Cull more code + FIXMEs

* Refactor of the resize system + polish

* Only draw frames when absolutely necessary

* Fix the tab-bar crash

* Fix rendering of boarders on reattach

* Fix resizing at small pane sizes

* Deduplicate code in the layout system

* Update tab-bar WASM

* Fixed the pinching of panes during resize

* Unexpose needlessly public type

* Add back a lost test

* Re-add tab tests and get them to compile

* All tabs need layouts

* Start fixing tests + bug in main

* Stabilize the resize algorithm rounding

* All tests from main are now passing

* Cull more dead code
2021-08-28 17:46:24 +01:00
Thomas Linford
94f20cfd53
Indicate to the user when text is copied to the clipboard (#642)
* Indicate to the user when text is copied to the clipboard

- broadcast CopyToClipboard event to plugins after selection has been
  copied, and InputReceived event after any input has been received.
- add new ClientToServerMsg InputReceived
- subscribe status-bar plugin to new events, modify second line after
  CopyToClipboard, reset it on InputReceived.

* remove unnecessary InputReceived ClientToServerMsg

- use existing Actions instead to know that user input has been received

* make status bar text copied hint bold green

* cleanup

* cleanup

* cleanup
2021-08-23 15:51:33 +02:00
Aram Drevekenin
a37d3e5889
feat(ui): pane frames (new pane UI) (#643)
* work

* resize working

* move focus working

* close pane working

* selection and fullscreen working

* pane title line

* titles and conditional scroll title

* whole tab resize working

* plugin frames working

* plugin splitting working

* truncate pane frame titles

* cleanup

* panes always draw their own borders - also fix gap

* toggle pane frames

* move toggle to screen and fix some bugs

* fix plugin frame toggle

* fix terminal window resize

* fix scrolling and fullscreen bugs

* unit tests passing

* e2e tests passing and new test for new frames added

* refactor: TerminalPane and PluginPane

* refactor: Tab

* refactor: moar Tab

* refactor: Boundaries

* only render and calculate boundaries when there are no pane frames

* refactor: Layout

* fix(grid): properly resize when coming back from alternative viewport

* style: remove commented code

* style: fmt

* style: fmt

* style: fmt + clippy

* docs(changelog): update change
2021-08-12 14:50:00 +02:00
Brooks J Rady
f2c5ee44f7 Getting back to where we started... (Buggy Resizing) 2021-05-29 23:12:11 +01:00
Aram Drevekenin
a3f42b19a9
Osc implementation (#517)
* fix(compatibility): implement most osc methods

* style(fmt): rustfmt

* style(fmt): remove cargo warnings

* style(fmt): make clippy happy

* style(fmt): fix formatting after my clippy fixes broke it again ;P

* fix(grid): fix tests
2021-05-17 18:13:05 +02:00
a-kenji
088bcf3dd8 Add Option for Simplified Layout
* the simplified layout omits the Nerdfonts characters that are not
  found in every Fontset

* add an optional config option to opt into the simplified ui
  `simplified_ui: bool`

* add a config flag that allows opting into the simplified ui
  `zellij options --simplified-ui`

* move the `clean` flag to the `setup` subcommand
2021-05-10 16:03:06 +02:00
Brooks J Rady
6e5600efc8 chore(plugin): shuffle helper library names and versions 2021-05-04 23:31:30 +01:00
Aram Drevekenin
1f88b342e2
fix(colors): stabilize colors (#453)
* fix(colors): stabilize colors

* style(fmt): rustfmt
2021-05-04 16:06:55 +02:00
denis
56cf446275 chore: added zellij-tile-extra, moved macros from zellij-tile 2021-05-02 12:57:48 +03:00
denis
d48cc81536 fix: don't have new on ColoredElements anymore, removed default for palette in zellij-tile 2021-05-02 12:25:49 +03:00
denis
61bb74ebbd chore: clippy please allow it 2021-05-01 15:10:21 +03:00
denis
f85822972a chore: cleanup, fix: the tests finally pass 2021-05-01 14:44:43 +03:00
denis
a8adfdfd60 wip: more cleaning up 2021-04-24 18:52:50 +03:00
denis
2e94ef51aa wip: trying to make it less messy so people don't hate me 2021-04-24 18:28:28 +03:00
denis
de72d3d2fb wip: tab bar coloring 2021-04-24 11:42:40 +03:00
denis
c44de89350 wip: colors adjustments 2021-04-24 11:25:09 +03:00
denis
fef466c74b wip: the only way to make the default look like on main is to make more customizable colored elements 2021-04-24 10:21:25 +03:00
denis
8d98ca7da0 wip: merge main in 2021-04-22 11:45:29 +03:00