Add branch drawing symbols to box characters #7681
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This symbols are for drawing git-like directed acyclic graphs in the terminal. Similar to box drawing characters, it is difficult to align these symbols perfectly when they're implemented only as font glyphs.
These codes are not based on any existing standard. I have implemented them using my experience creating the terminal-based branch viewer and vim plugin vim-flog. I plan to use these symbols in flog.
Here is what the symbols look like in kitty, in order:
Symbol order
The order is similar to the original box-drawing characters. Particularly, where there are symbols with a mix of light lines and heavy lines, I replace the heavy lines with curves. Otherwise, I try to follow a similar order.
Symbol purposes
Some symbols effectively already exist, these ones in particular:
Providing these symbols and not relying on the existing box symbols allows customizing line thickness and style only for branch viewers and not anything else that uses box drawing characters. This is not really required if we consider this unicode range only for a terminal that draws box drawing characters, but as a general standard symbol range I think it's good to have.
These symbols represent merging up into an existing branch from the right or left:
These symbols represent forking out from an existing branch to the right or left:
These symbols are for merges; merging into an ongoing merge line from the right or left; merging up from the right and left into a new branch above; merging up from the right and left into an existing branch (note the vertical alignment here is not as shown, see the first screenshot of all symbols for the actual alignment):
A very particular, somewhat confusing situation, but possible while trying to preserve horizontal space; merge from the left while reordering the parent to the right under the branch:
A branch "fading out" - used to represent branches that don't have any more parents in the otuput:
Merge commits and non-merge commits; disconnected, connected on one side, and connected on both sides:
You might notice that the commit is not perfectly centered on the line. It does not look like this on every font size. This is because the line is aligned with non-supersampled lines, but the circles themselves are supersampled.
The symbols I detailed above are all the symbols you need to represent the typical left-aligned, top-to bottom git commit graph visualization. However, since this is meant to be a general standard, I have included symbols for aligning the graph in any other direction.
Range selection
I selected a range (0xf5d0 - 0xf5fb) in a Unicode Private Use Area that is a reasonable distance from the previous icon set in Nerd icons.
This range is not in use by Fira Code or Nerd Fonts or any other icon/symbol set I could find.
Here is the unused range in Fira Code as visualized in FontForge:
Here is the unused range in a Nerd font:
New Code
Added functions to draw branches fading out. I tried to apply the existing "hole" functions for this purpose, or at least implement similar functions, but it was much easier to draw only the solid part of these symbols rather than cutting out the holes. This is because they look best when they are symmetrical with their mirror images, not touching the side that they are fading out towards, and touching the side that they are fading out from. The existing hole functions were not ideal for expressing any of these properties, at least in a way I could find, even though you can fairly easily achieve similar spacing.
Added a function for drawing circles. I could not find a great way to use any of the existing circular functions to create filled in circles; and at very small font sizes, these generate what look like rounded squares, not circles. In addition, it was easier to cut out the center of the center of non-merge commits than to draw tiny lines in the correct position in a way that works in every font size, and it looks more visually consistent than drawing arcs as well, so the circle function is used to both fill in and cut out circles.
Code Changes
draw_hline
anddraw_vline
. This is because of the number of lines I needed to draw in supersampled functions that had to line up with non-supersampled lines (namely commits and fading branches).