Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consistent statusline spacing #7310

Closed

Conversation

hamrik
Copy link
Contributor

@hamrik hamrik commented Jun 10, 2023

Statusline elements used to have inconsistent spacing due to each element having to pad itself without knowledge of surrounding elements.

Inconsistent spacing
  • mode, selections, file-name and position are padded, the rest are not
  • file-modification-indicator reserves space for itself, spinner and diagnostics do not

This PR fixes these spacing inconsistencies.

Consistent spacing
  • No elements pad themselves
  • No elements reserve empty space
  • The statusline pads everything
  • The spacer element has been repurposed to join multiple spacers, e.g. to pad the ends of the statusline

The render functions of statusline elements previously used an ad-hoc write callback to blit Spans directly to the Surface of the statusline. This callback has been removed. Now each render function has to return the Spans it wants to display, which the renderer of the statusline collects, intersperses with spaces, then blits to the surface.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch 2 times, most recently from ef9d76a to 1c3a8b0 Compare June 11, 2023 09:01
@gabydd
Copy link
Member

gabydd commented Jun 12, 2023

At first look one thing that this changes that we probably shouldn't is it removes padding around the edges in the default config which imo we should keep especially looks bad when color-modes is false. This brings up another question if we are going for consistency do we really want modes size to be dependant on coior-modes? I haven't looked much at the implementation but I think improving consistency is generally good as long as we are not breaking peoples configs.

@David-Else
Copy link
Contributor

@gabydd Regarding color -modes: #7289 (comment)

@gabydd
Copy link
Member

gabydd commented Jun 12, 2023

Ah right, I only noticed this because I don't use color-modes. Removing the option is probably a good idea in the long run though.

helix-term/src/ui/statusline.rs Show resolved Hide resolved
helix-tui/src/text.rs Outdated Show resolved Hide resolved
helix-tui/src/text.rs Outdated Show resolved Hide resolved
helix-tui/src/text.rs Outdated Show resolved Hide resolved
helix-tui/src/text.rs Outdated Show resolved Hide resolved
helix-tui/src/text.rs Outdated Show resolved Hide resolved
book/src/configuration.md Outdated Show resolved Hide resolved
@pascalkuthe
Copy link
Member

pascalkuthe commented Jun 13, 2023

I am not sure if we need the editor.statusline.spacer config. Why would this be ever set to anything but space?

@kirawi kirawi added C-enhancement Category: Improvements A-helix-term Area: Helix term improvements S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 15, 2023
@hamrik
Copy link
Contributor Author

hamrik commented Jun 22, 2023

Sorry for disappearing, had a busy couple of weeks. Checking the responses right now.

@hamrik
Copy link
Contributor Author

hamrik commented Jun 22, 2023

At first look one thing that this changes that we probably shouldn't is it removes padding around the edges in the default config which imo we should keep especially looks bad when color-modes is false. This brings up another question if we are going for consistency do we really want modes size to be dependant on coior-modes? I haven't looked much at the implementation but I think improving consistency is generally good as long as we are not breaking peoples configs.

I originally didn't have padding in color-modes either, but then the background color cut right off at the end of the mode name, leaving no padding inside the element. It just didn't look right. I agree that this makes modes a bit inconsistent and will have to think of something to address this.

Padding the statusbar edges could be done by changing the default config to include spacer-s on the sides.
Alternatively I could force padding into the statusline, but then color-modes won't look right and the user won't be able to fix it by removing a spacer, so I vote for chaging the default config.
Those who have customized statusline configs shouldn't have a hard time adding a spacer if they don't use color-modes.

@hamrik
Copy link
Contributor Author

hamrik commented Jun 22, 2023

I am not sure if we need the editor.statusline.spacer config. Why would this be ever set to anything but space?

A couple examples:

  • Two or more spaces for wider spacing without spamming spacer: file.txt 1:1 [+]
  • Powerline-style (colorless) separators: file.txt 〉1:1 〉[+]
    • Altough to make this last one flippable we would have to add separate spacer configs for left, center and right.
    • EDIT: I guess there's separator, but changing spacer width is still a valid reason for keeping it in my opinion.

@pascalkuthe
Copy link
Member

Generally I would prefer explicit spacers since it allows different spacing between different elements without adding a ton new config options. I don't think that the spacing inside of elements needs to be configurable. We are shooting for a mininal config file.

@hamrik
Copy link
Contributor Author

hamrik commented Jun 22, 2023

You are free to leave editor.statusline.spacer on the default setting and use spacers. It don't feel it's out of place next to the configurable separator and configurable mode names.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 8e8d860 to 51dedf3 Compare July 14, 2023 07:27
@gabydd gabydd mentioned this pull request Jul 30, 2023
@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 51dedf3 to 1a0ad99 Compare August 11, 2023 15:54
@pascalkuthe
Copy link
Member

You are free to leave editor.statusline.spacer on the default setting and use spacers. It don't feel it's out of place next to the configurable separator and configurable mode names.

we are very conservative with regards to adding new config options and this doens' cross the bar for me. The rest of the PR is probably a nice improvement but I don't see us adding this config option

@hamrik
Copy link
Contributor Author

hamrik commented Aug 11, 2023

While I personally disagree, I've removed the option so we can move on. At least that solved the documentation wording problem. We can revisit this in a later PR.

@hamrik
Copy link
Contributor Author

hamrik commented Aug 11, 2023

I believe the only two remaining issues are the spacing of the mode indicator and the spinner. The spinner discussion is happening in the review.

I don't like the idea of hardcoding spacers on the edges, in my opinion modifying the default config to include spacers would be more flexible.

But regardless of how the padding is handled, it would look weird the color modes option turned on.

If we go with the hardcoded route, we could omit adding spacers where the mode indicator is the first/last item and color modes are enabled. But this feels like a hack.

If we go with the modified default config, we could add/omit the spacer depending on whether we enable color modes by default, then expect people to add/remove the spacer manually if they change the color modes option.

On a similar note, right now padding is automatically added to the mode indicator when color-modes are on, but that could also be removed if we expect people to modify the mode names to include spaces when they toggle color modes.

Thoughts?

@hamrik
Copy link
Contributor Author

hamrik commented Aug 12, 2023

I have removed the auto-padding from the mode element, regardless of color-modes.

  • This makes the mode element consistent with the other elements.
  • If color-modes is off by default, people who turn it on can add padding via editor.statusline.mode.
  • If color-modes becomes default, the default values for mode names can also be tweaked to include spaces.

@pascalkuthe
Copy link
Member

Yeah I agree with that. I think hardcoded padding is never a good idea and changing the modenames is a pretty good workaround IMO

Copy link
Member

@pascalkuthe pascalkuthe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is very hard to review right now because you changed the order of some.functions (and in general have included some unnecessary changes) sk the diff is pretty clobbered right now.

Could you undo that so it's easier for us to see what's actually changed

@pascalkuthe
Copy link
Member

Also I am not really sure if we really want the implhct spacer between each element. I actually lprefer having no implicit spacer at all and instead including the necessary specaers in the default config. This offers the most flexibility and is the easiet to implement

@hamrik
Copy link
Contributor Author

hamrik commented Aug 12, 2023

I actually lprefer having no implicit spacer at all and instead including the necessary specaers in the default config.

Since some elements only appear occasionally (such as file-modification-indicator, spinner, etc) these would leave two spacers behind whenever they are hidden (assuming the config has explicit spacers between every element). Implementing collapsing spacers would be even more complicated IMO.

Example:

 NOR implicit_spacing.txt 1:1
 NOR implicit_spacing.txt [+] 1:2

vs

 NOR explicit_spacing.txt  1:1
 NOR explicit_spacing.txt [+] 1:2

@hamrik
Copy link
Contributor Author

hamrik commented Aug 12, 2023

This PR is very hard to review right now because you changed the order of some.functions (and in general have included some unnecessary changes) sk the diff is pretty clobbered right now.

I'll clean up the commit history on the weekend.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 4d8bf16 to d920bb5 Compare August 13, 2023 21:22
@hamrik hamrik marked this pull request as draft August 13, 2023 21:22
@hamrik
Copy link
Contributor Author

hamrik commented Aug 13, 2023

Okay, I've removed all additions to Spans, and consolidated the changes into two commits/"phases":

  1. Refactor statusline elements to return Spans rather than using a callback. At this point the spacing behavior is identical to the master branch.
  2. Removed padding from all statusline elements.

Right now there is no spacing interspersed as Iterator::intersperse() is in nightly for now. While this matches what @pascalkuthe requested I think spaces should be added because manually interspersed spacers don't collapse when an element hides itself, such as file-modification-indicator, leaving two spacers next to each other, which looks inconsistent.

Will address that later.

@hamrik
Copy link
Contributor Author

hamrik commented Aug 25, 2023

Added back automatic interspersing of spaces. Does not pad the sides of the panel, those should be done in config.

Uses a custom interspersing iterator until intersperse() lands in stable Rust. I'm fairly certain that its implementation should be moved elsewhere, not yet sure where would be best.

As for the spinner, I think simply hiding it is the most consistent behavior with other auto-hiding elements like file-modification-indicator. If the jumpyness is annoying it can be moved to a place where it does not push other elements around, such as the inner edge of the left and right sections. Maybe in the future it could get a debouncer so that split-second LSP activity does not trigger it.

@hamrik
Copy link
Contributor Author

hamrik commented Aug 25, 2023

The only thing remaining to tweak in my opinion is the default config. After that I'll reopen the PR.

On the left section:

  • If color-modes becomes the default then the default mode strings should be padded with spaces.
  • If it does not than an extra spacer needs to be prepended to the default element list.

On the right section:

  • A spacer needs to be appended to the default element list.

@hamrik
Copy link
Contributor Author

hamrik commented Aug 26, 2023

Added spacers to the default config to pad the statusline on the edges, with the assumption that color-modes will remain off by default for now.

People who want to enable it and have it look good will have to:

  1. Enable color-modes
  2. Set custom mode strings that include spaces, e.g. normal = " NOR "
  3. Set a custom left section that does not begin with spacer

Debating whether this should be documented.
Also fixed the bug where spacer adds an extra space by accident, which was introduced in the cleanup.

The intersperse implementation still needs a better place, but I think it's OK to reopen the PR by this point.

@hamrik hamrik marked this pull request as ready for review August 26, 2023 21:31
@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 4ce242d to e54391a Compare September 6, 2023 21:18
@hamrik hamrik force-pushed the consistent_statusline_spacing branch from e54391a to f661c0c Compare September 25, 2023 13:53
@the-mikedavis the-mikedavis added S-waiting-on-review Status: Awaiting review from a maintainer. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 25, 2023
@hamrik
Copy link
Contributor Author

hamrik commented Sep 27, 2023

I was thinking about color-modes lately. Since the goal is to eventually remove the option altogether, maybe this would be a good time to set it to true by default and incorporate the rest of the tweaks mentioned above into the default config.

It would still look better for people who turn the feature off than it does now when people turn it on without the tweaks.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 86f8538 to 1491768 Compare October 7, 2023 16:23
@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 1491768 to de7776b Compare November 22, 2023 12:22
@hamrik
Copy link
Contributor Author

hamrik commented Nov 22, 2023

Looks like intersperse won't make into the stdlib anytime soon so I introduced the itertools dependency to avoid reinventing the wheel.

If this is a problem I can revert the last commit, before which a hand-rolled solution was used add spacers between statusline elements.

@the-mikedavis
Copy link
Member

I would like to avoid itertools if possible - it's a fair amount of code to add for things that can usually be written inline. Here I think it's cleaner to use a helper function that returns Spans:

fn join_with_spaces<'a, I: Iterator<Item = Span<'a>>>(iter: I) -> Spans<'a> {
    let mut spans = Vec::new();
    for elem in iter {
        if !spans.is_empty() {
            spans.push(Span::raw(" "));
        }
        spans.push(elem);
    }
    spans.into()
}

// ..

context.parts.left = join_with_spaces(
    element_ids
        .iter()
        .map(|element_id| get_render_function(*element_id))
        .flat_map(|render| render(context).0),
);

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 6b275c6 to 759378d Compare November 22, 2023 17:29
@hamrik
Copy link
Contributor Author

hamrik commented Nov 22, 2023

Okay, I have reversed the inclusion and also replaced the hand-rolled interspersing iterator with your helper function.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from 759378d to a862f1a Compare December 8, 2023 09:45
@hamrik
Copy link
Contributor Author

hamrik commented Dec 8, 2023

Debating whether to increase spacing between elements from one to two spaces.

@hamrik hamrik force-pushed the consistent_statusline_spacing branch from a862f1a to c63d3de Compare December 19, 2023 08:58
@hamrik
Copy link
Contributor Author

hamrik commented Dec 19, 2023

Increased spacing to two spaces, which actually looks closer to how spacing looked before the PR.

@hamrik
Copy link
Contributor Author

hamrik commented Dec 19, 2023

Double spacing breaks consistency next to mode when color-modes is on. Argh!

This PR became a mess, so I'm closing it and will make a new one with a smaller scope.

EDIT: Superseded by #9122

@hamrik hamrik closed this Dec 19, 2023
@hamrik hamrik deleted the consistent_statusline_spacing branch March 20, 2024 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements C-enhancement Category: Improvements S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants