Skip to content

Commit

Permalink
Merge pull request #13 from graemedavidson/v2
Browse files Browse the repository at this point in the history
copied v0.2 from exploratory branch
  • Loading branch information
graemedavidson authored May 16, 2023
2 parents db2fc7c + d807186 commit 2331518
Show file tree
Hide file tree
Showing 19 changed files with 653 additions and 332 deletions.
3 changes: 1 addition & 2 deletions .shellspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
--require spec_helper

## Default kcov (coverage) options
--kcov-options "--include-path=./scripts --path-strip-level=1"
--kcov-options "--include-pattern=.sh"
--kcov-options "--include-path=./scripts/functions.sh --path-strip-level=1"
--kcov-options "--exclude-pattern=/.shellspec,/spec/,/coverage/,/report/"

## Example: Include script "myprog" with no extension
Expand Down
3 changes: 2 additions & 1 deletion .tmux.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ set -g @plugin 'tmux-plugins/tmux-sensible'
# Install through github disabled as not useful for local development
# set -g @plugin 'graemedavidson/tmux-focus'

set -g @pane-focus-enabled on
set -g @pane-focus-size '50'
set -g @pane-focus-direction '+'

set -g status-right '#[fg=colour255,bg=colour237][#{@pane-focus-direction}][#{@pane-focus-size}]#[fg=default,bg=default]'
set -g status-right '#[fg=colour255,bg=colour237][#{@pane-focus-direction} #{@pane-focus-size}% #{@pane-focus-enabled}]#[fg=default,bg=default]'

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential=12.9ubuntu3 \
ca-certificates=20211016ubuntu0.22.04.1 \
fzf=0.29.0-1 \
git=1:2.34.1-1ubuntu1.8 \
git=1:2.34.1-1ubuntu1.9 \
libevent-dev=2.1.12-stable-1build3 \
libncurses-dev=6.3-2 \
wget=1.21.2-2ubuntu1 \
Expand Down
99 changes: 30 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,25 @@
Tmux plugin to auto resize panes on focus similar to [nvim Focus](https://github.com/beauwilliams/focus.nvim).
On focusing on another pane the hook `after-select-pane` calls the focus script.

Auto resize size and direction set for all windows in the `.tmux.conf` file and then overridden locally via the options
menu.

- Size: >=50, <100.
- Direction:
- `+`: both
- `|`: vertical (width) changes only
- `-`: horizontal (height) changes only
- `|`: width changes only
- `-`: height changes only

```conf
set -g @pane-focus-size '50'
set -g @pane-focus-size '+'
```

Change size setting per session by activating menu with tmux shortcut: `ctrl-a T`.
## Installation

Add current active size to status bar:
### Tmux Plugin Manager

```conf
set -g status-right '#[fg=colour255,bg=colour237][#{@pane-focus-direction}][#{@pane-focus-size}]#[fg=default,bg=default]'
Add plugin GitHub url to list of tpm plugins. Specify tag/branch for specific version.

```
set -g @plugin 'graemedavidson/tmux-pane-focus'
# set -g @plugin 'graemedavidson/tmux-pane-focus#tag'
```

## Installation
### Manual

Clone repo into tmux plugins dir.

Expand All @@ -37,74 +33,39 @@ Add run shell command to end of `.tmux.conf` file to activate plugin.
run-shell '~/.tmux/plugins/tmux-pane-focus/focus.tmux'
```

ToDo: review installing plugin via [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm)

## Architecture

Currently plugin determines window and appropriate pane size for active and inactive and then resizes all panes on an
plane. So resize panes top to bottom and left to right.

Plugin language is bash matching the majority of tmux plugins. Bash allows for portability but the language has
limitations. Considerations to moving towards another scripting language for example python in pipeline.

## Local Development
## Configuration

Local development leverages a basic docker compose and docker file setup. Setup should respond to changes made to the
scripts without requiring restarts.
Enable/Disable plugin:

- [Docker Build File](./Dockerfile)
- [Docker Compose](./docker-compose.yml)

Build the local image and run:

```bash
docker-compose build
docker-compose run tmux
```

Create and move between new panes:

| Binding | Action
| --- | ---
| `ctrl-a |` | Create vertical pane
| `ctrl-a -` | Create horizontal pane
| `ctrl-a <DIRECTION_KEY>` | Move between panes
| `ctrl-a T` | Pane Focus menu to change percentage for active pane

### Shellspec Tests

Unit tests included through [shellspec](https://shellspec.info/) within a [container](https://hub.docker.com/r/shellspec/shellspec-debian/tags).

- [Tests](./spec/)

```bash
docker-compose run tests
docker run -it --rm -v "$PWD:/src" --entrypoint bash shellspec/shellspec-debian:0.28.1
set -g @pane-focus-size on
```

### Tmux Setup
Add configuration to the `.tmux.conf` file to override the following defaults:

Tmux configured to use `ctrl-a` as well as other opinionated settings.
- focus size: `50%`
- focus direction: `+`

- [tmux config](./.tmux.conf)
```conf
set -g @pane-focus-size '50'
set -g @pane-focus-direction '+'
```

[Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) included with automatic installation of
[Tmux Sensible](https://github.com/tmux-plugins/tmux-sensible).
### Settings Menu

### Pre-Commit
The default and global settings can be overridden at the window level through an options menu.

[Pre-Commit](https://pre-commit.com/).
tmux shortcut: `ctrl-a T`.

- [./.pre-commit-config.yaml]
### Status bar

Install pre-commit hooks:
Add current active size and direction to status bar:

```bash
pre-commit install
```conf
set -g status-right '#[fg=colour255,bg=colour237][#{@pane-focus-direction}][#{@pane-focus-size}]#[fg=default,bg=default]'
```

Run against all files:
## Known Issues

```bash
pre-commit run --all-files
```
- Changes to inactive pane impeded by other panes.
- Add example
4 changes: 4 additions & 0 deletions docs/INDEX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Documentation

- [architecture](./architecture.md)
- [local development](./development.md)
175 changes: 175 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Architecture

Plugin uses window height and width and the current active percentage size setting to calculate the minimum size of
active pane. If the active pane is lower than the calculated size a list of panes within the row or column of the active
pane calculated and then updated. If the active pane is greater than the calculated minimum no changes occur.

The plugin makes use of the tmux API to modify tmux state. Review tmux man page or [online documentation](http://man.openbsd.org/OpenBSD-current/man1/tmux.1)

## Glossary

- row: horizontal set of panes in which the active pane sits.
- col/column: vertical set of panes in which the active pane sits.
- height: integer value for window or pane.
- width: integer value for window or pane.
- horizontal splits `_`: the number of splits separating panes top to bottom.
- vertical splits `|`: the number of splits separating panes left to right.
- window: A window within a tmux session containing panes
- pane: a individual command prompt within a window
- pane sides: integer value for position within grid (top, bottom, left, and right)
- axis: y representing height and, x representing width

Plugin refers to the x plane as `row` and the y plane as `column` within the code.

## Change Ordering

Currently configured to change size of height then width.

## Pane Limits

Plugin determines the number of panes at start.

if 1 pane, quit.

Currently no upper limit on panes defined, considering changes as resolving complicated layouts with several panes leads
to more erroneous results.

## Active Pane

The plugins main function is to resize the active pane selected by the user to the currently configured active
percentage size. The plugin calculates the remaining screen space divided by number of inactive panes and resizes
accordingly. Design intended to leave inactive panes legible where possible.

## Rows and Columns

Plugin optimised to determine all panes sitting on the x and y planes of the active pane. Therefore all inactive panes
outside of the active pane not resized to reduce plugin operations. Plugin accounts for overlapping panes.

The following examples show each inactive pane found in the column and row of the active pane.

Row Examples:

![Row Example 1](./images/row-example-1.png)
![Row Example 2](./images/row-example-2.png)

Column Examples:

![Column Example 1](./images/column-example-1.png)
![Column Example 2](./images/column-example-2.png)
![Column Example 2](./images/column-example-3.png)

## Parent Panes

When tmux resizes a pane any adjacent panes on the column or row is also resized, so for example, a resize command on
pane 1 would change the size of panes 2, 3 and 4 in the below diagrams. The last diagram should return to the same as
the start diagram.

```
# start select pane 1 (increase) select pane 0 (decrease)
--------------- --------------- ---------------
| 0 | 1 | | 0 | 1 | | 0 | 1 |
| |-------| | |----------| | |---|
| | 2 | 3 | | | 2 | 3 | | |2|3|
| |-------| | |----------| | |---|
| | 4 | | | 4 | | | 4 |
--------------- --------------- ---------------
```

Plugin determines parent panes by maintaining a stack and pushing when greater value of left or top and pushing when lower
value of left or top. This matches the internal tmux index ordering which moves left to write then top down, so in the
below example pane 3 sits under pane 2, not to the right of it.

```
---------------
| 0 | 1 |
| |-------|
| | 2 | 4 |
| |-------|
| | 3 | 5 |
---------------
```

To account for this parent panes have a multiplier value calculated for each child pane and children with same
dimensions aren't added to the resize list. The following examples describe the expected feature.

Parents determined for rows and columns separately.

### Column example

Changing width when selecting pane 1

```
---------------
| 0 | 1 |
| |-------|
| | 2 | 3 |
| |-------|
| | 4 |
---------------
```

- Pane 2, 3, and 4 are children of pane 1.
- Pane 1, 2, and 3 added to list of panes requiring resize.
- Pane 4 omitted from resize list; same size of parent pane on left and right margins.
- Pane 1 has multiplier of 2.
- Pane 0 resized to active size
- Pane 1 resized to inactive size * 2
- Pane 2, and 3 resized to inactive size

### Row example

Changing height when selecting pane 1

```
---------------
| 0 |
|---------------|
| 1 | 2 | 3 |
|---------------|
| 4 | 5 |
---------------
```

- Pane 0, 4, and 5 omitted as not in active pane row.
- Pane 1 not a parent pane as its the active pane.
- Pane 3 child of pane 2.
- Pane 3 omitted from resize list; same size of parent pane on top and bottom margins
- Pane 1 resized to active size
- Pane 2 resized to inactive size

## Resizing

Plugin makes use of the `tmux resize-pane` command to change a pane.

Targeting of a pane by `-t` parameter when running the resize command. Command accepts an id with the `%` prefix or
an index number. The plugin uses the index value internally for uniquely identifying each pane.

The ordering of changes is from top left to bottom right following the inbuilt [indexing](#indexes) of tmux.

### Indexes

The indexes of current panes shown with command:

```
Ctrl-A q
```

List all panes indexes in order:

```
tmux list-panes -F "#{pane_index}" | sort -n
```

![Pane indexes](./images/index.png)

## Language

Plugin language is bash matching the majority of tmux plugins. Bash allows for portability but the language has
limitations. Considerations to moving towards another scripting language for example python in pipeline.

## Global and Local variables

Global variable accessed using the `-g` flag and within the context of this plugin provides access to the configuration
set in the [tmux conf file](#configuration) used as default for all new sessions and windows. Global settings can be
overridden per window with the [settings menu](#setting-menu). The menu uses the `-w` flag to set the option at the
window level.
Loading

0 comments on commit 2331518

Please sign in to comment.