-
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1459 from contour-terminal/feature/customizable-s…
…tatusline Add customizable statusline
- Loading branch information
Showing
25 changed files
with
1,294 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Indicator Statusline | ||
|
||
The indicator statusline used to be a feature, from the old DEC VT level 4 terminals. | ||
Contour revives this feature to prominently show the terminal status. | ||
|
||
## Configuration | ||
|
||
``` | ||
profiles: | ||
your_profile: | ||
status_line: | ||
indicator: | ||
left: "{VTType} │ {InputMode:Bold,Color=#C0C030}{SearchPrompt:Left= │ }{TraceMode:Bold,Color=#FFFF00,Left= │ }{ProtectedMode:Bold,Left= │ }" | ||
middle: "{Title:Left= « ,Right= » ,Color=#20c0c0}" | ||
right: "{HistoryLineCount:Faint,Color=#c0c0c0} │ {Clock:Bold} " | ||
``` | ||
|
||
Each segment, `left`, `middle`, and `right` may contain text to be displayed in the | ||
left, middle, or right segment of the indicator statusline. | ||
|
||
This text may contain placeholders to be replaced by their respective dynamic content. | ||
|
||
## Variables | ||
|
||
Variable | Description | ||
---------------------|-------------------------------------------------------------------- | ||
`{Clock}` | current clock in HH:MM format | ||
`{Command}` | yields the result of the given command prompt, as specified via parameter `Program=...` | ||
`{HistoryLineCount}` | number of lines in history (only available in primary screen) | ||
`{Hyperlink}` | reveals the hyperlink at the given mouse location | ||
`{InputMode}` | current input mode (e.g. INSERT, NORMAL, VISUAL) | ||
`{ProtectedMode}` | indicates protected mode, if currently enabled | ||
`{SearchMode}` | indicates search highlight mode, if currently active | ||
`{SearchPrompt}` | search input prompt, if currently active | ||
`{Text}` | given text (makes only sense when customized with flags) | ||
`{Title}` | current window title | ||
`{VTType}` | currently active VT emulation type | ||
|
||
## Formatting Styles | ||
|
||
Each Variable, as specified above, can be parametrized for customizing the look of it. | ||
The common syntax to these variables and their parameters looks as follows: | ||
|
||
``` | ||
{VariableName:SomeFlag,SomeKey=SomeValue} | ||
``` | ||
|
||
So parameters can be specified after a colon (`:`) as a comma separated list of flags and key/value pairs. | ||
A key/value pair is further split by equal sign (`=`). | ||
|
||
The following list of formatting styles are supported: | ||
|
||
Parameter | Description | ||
--------------------------|-------------------------------------------------------------------- | ||
`Left=TEXT` | text to show on the left side, if the variable is to be shown | ||
`Right=TEXT` | text to show on the right side, if the variable is to be shown | ||
`Color=#RRGGBB` | text color in hexadecimal RGB notation | ||
`BackgroundColor=#RRGGBB` | background color in hexadecimal RGB notation | ||
`Bold` | text in bold font face | ||
`Italic` | text in italic font face | ||
`Underline` | underline text (only one underline style can be active) | ||
`CurlyUnderline` | curly underline text (only one underline style can be active) | ||
`DoubleUnderline` | double underline text (only one underline style can be active) | ||
`DottedUnderline` | dotted underline text (only one underline style can be active) | ||
`DashedUnderline` | dashed underline text (only one underline style can be active) | ||
`Blinking` | blinking text | ||
`RapidBlinking` | rapid blinking text | ||
`Overline` | overline text | ||
`Inverse` | inversed text/background coloring | ||
|
||
These parameters apply to all variables above. | ||
|
||
The `Command` variable is the only one that requires a special attribute, `Program` whose value | ||
is the command to execute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#include <crispy/interpolated_string.h> | ||
|
||
namespace crispy | ||
{ | ||
|
||
namespace | ||
{ | ||
void parse_attribute(string_interpolation* interpolation, std::string_view attribute) | ||
{ | ||
auto const equal = attribute.find('='); | ||
if (equal != std::string_view::npos) | ||
{ | ||
auto const key = attribute.substr(0, equal); | ||
auto const value = attribute.substr(equal + 1); | ||
interpolation->attributes[key] = value; | ||
} | ||
else | ||
{ | ||
interpolation->flags.insert(attribute); | ||
} | ||
} | ||
} // anonymous namespace | ||
|
||
string_interpolation parse_interpolation(std::string_view text) | ||
{ | ||
auto result = string_interpolation {}; | ||
auto const colon = text.find(':'); | ||
if (colon != std::string_view::npos) | ||
{ | ||
result.name = text.substr(0, colon); | ||
auto const attributes = text.substr(colon + 1); | ||
size_t pos = 0; | ||
while (pos < attributes.size()) | ||
{ | ||
auto const comma = attributes.find(',', pos); | ||
if (comma == std::string_view::npos) | ||
{ | ||
parse_attribute(&result, attributes.substr(pos)); | ||
break; | ||
} | ||
else | ||
{ | ||
parse_attribute(&result, attributes.substr(pos, comma - pos)); | ||
pos = comma + 1; | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
result.name = text; | ||
} | ||
return result; | ||
} | ||
|
||
interpolated_string parse_interpolated_string(std::string_view text) | ||
{ | ||
// "< {Clock:Bold,Italic,Color=#FFFF00} | {VTType} | {InputMode} {Search:Bold,Color=Yellow} >" | ||
|
||
auto fragments = interpolated_string {}; | ||
|
||
size_t pos = 0; | ||
while (pos < text.size()) | ||
{ | ||
auto const openBrace = text.find('{', pos); | ||
if (openBrace == std::string_view::npos) | ||
{ | ||
// no more open braces found, so we're done. | ||
fragments.emplace_back(text.substr(pos)); | ||
return fragments; | ||
} | ||
|
||
if (auto const textFragment = text.substr(pos, openBrace - pos); !textFragment.empty()) | ||
// add text fragment before the open brace | ||
fragments.emplace_back(textFragment); | ||
|
||
auto const closeBrace = text.find('}', openBrace); | ||
if (closeBrace == std::string_view::npos) | ||
{ | ||
// no matching close brace found, so we're done. | ||
fragments.emplace_back(parse_interpolation(text.substr(openBrace))); | ||
return fragments; | ||
} | ||
else | ||
{ | ||
// add interpolation fragment | ||
auto const fragment = text.substr(openBrace + 1, closeBrace - openBrace - 1); | ||
fragments.emplace_back(parse_interpolation(fragment)); | ||
pos = closeBrace + 1; | ||
} | ||
} | ||
|
||
return fragments; | ||
} | ||
|
||
} // namespace crispy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#pragma once | ||
|
||
#include <map> | ||
#include <set> | ||
#include <string_view> | ||
#include <variant> | ||
#include <vector> | ||
|
||
namespace crispy | ||
{ | ||
|
||
struct string_interpolation | ||
{ | ||
std::string_view name; | ||
std::set<std::string_view> flags; | ||
std::map<std::string_view, std::string_view> attributes; | ||
|
||
bool operator==(string_interpolation const& rhs) const noexcept | ||
{ | ||
return name == rhs.name && flags == rhs.flags && attributes == rhs.attributes; | ||
} | ||
|
||
bool operator!=(string_interpolation const& rhs) const noexcept { return !(*this == rhs); } | ||
}; | ||
|
||
using interpolated_string_fragment = std::variant<string_interpolation, std::string_view>; | ||
using interpolated_string = std::vector<interpolated_string_fragment>; | ||
|
||
string_interpolation parse_interpolation(std::string_view text); | ||
interpolated_string parse_interpolated_string(std::string_view text); | ||
|
||
} // namespace crispy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include <crispy/interpolated_string.h> | ||
|
||
#include <fmt/format.h> | ||
|
||
#include <catch2/catch_test_macros.hpp> | ||
|
||
TEST_CASE("interpolated_string.parse_interpolation") | ||
{ | ||
using crispy::parse_interpolation; | ||
|
||
auto const interpolation = parse_interpolation("Clock:Bold,Italic,Color=#FFFF00"); | ||
CHECK(interpolation.name == "Clock"); | ||
CHECK(interpolation.flags.size() == 2); | ||
CHECK(interpolation.flags.count("Bold")); | ||
CHECK(interpolation.flags.count("Italic") == 1); | ||
CHECK(interpolation.attributes.size() == 1); | ||
CHECK(interpolation.attributes.count("Color")); | ||
CHECK(interpolation.attributes.at("Color") == "#FFFF00"); | ||
} | ||
|
||
TEST_CASE("interpolated_string.parse_interpolated_string") | ||
{ | ||
using crispy::parse_interpolated_string; | ||
|
||
auto const interpolated = parse_interpolated_string("< {Clock:Bold,Italic,Color=#FFFF00} | {VTType}"); | ||
|
||
CHECK(interpolated.size() == 4); | ||
|
||
REQUIRE(std::holds_alternative<std::string_view>(interpolated[0])); | ||
REQUIRE(std::get<std::string_view>(interpolated[0]) == "< "); | ||
|
||
REQUIRE(std::holds_alternative<crispy::string_interpolation>(interpolated[1])); | ||
|
||
REQUIRE(std::holds_alternative<std::string_view>(interpolated[2])); | ||
REQUIRE(std::get<std::string_view>(interpolated[2]) == " | "); | ||
|
||
REQUIRE(std::holds_alternative<crispy::string_interpolation>(interpolated[3])); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.