website/docs/contributing/segment.mdx
Adding a new segment to Oh My Posh involves several steps to ensure proper integration. This guide walks you through creating a complete segment with all necessary files and registrations.
Before coding, define these key properties:
new-feature)NewFeature)cli, cloud, health, languages, music, scm, system, or web{{ .Text }})If you're using VS Code, you can use the automated segment creation command in VS Code Chat:
/segment and follow the promptsThis automated approach ensures all files are created correctly with proper naming conventions and alphabetical ordering. If you prefer to create the segment manually or want to understand the process, continue with the manual steps below.
Create a new file in ./src/segments/ named after your segment ID: new_feature.go.
package segments
import (
"github.com/jandedobbeleer/oh-my-posh/src/segments/options"
)
type NewFeature struct {
Base
// Fields that will be available in your template
Text string
}
// Define constants for each configurable property
const (
// EnableNewThing enables the new functionality
EnableNewThing options.Property = "enable_new_thing"
// CustomText sets custom display text
CustomText options.Property = "custom_text"
)
func (n *NewFeature) Enabled() bool {
// Set up data for the template using property values
n.Text = n.props.GetString(CustomText, "default value")
// Return true if the segment should be displayed
// You can add logic here to determine if the segment is relevant
return true
}
func (n *NewFeature) Template() string {
return "{{ .Text }}"
}
Key Guidelines:
"\uEFF1") instead of the actual iconsEnabled() focused on data preparation and visibility determinationEdit src/config/segment_types.go to register your new segment:
In the init() function, add your segment to the gob registry (maintain alphabetical order):
gob.Register(&segments.NewFeature{})
Add a constant for your segment type (maintain alphabetical order):
// NEWFEATURE displays new feature information
NEWFEATURE SegmentType = "new-feature"
Register your segment in the Segments map (maintain alphabetical order):
NEWFEATURE: func() SegmentWriter { return &segments.NewFeature{} },
Create documentation at website/docs/segments/[category]/[segment-id].mdx:
---
id: new-feature
title: New Feature
sidebar_label: New Feature
---
## What
Displays information about the new feature in your environment.
## Sample Configuration
import Config from "@site/src/components/Config.js";
<Config
data={{
type: "new-feature",
style: "powerline",
powerline_symbol: "\uE0B0",
foreground: "#193549",
background: "#ffeb3b",
options: {
enable_new_thing: true,
custom_text: "Hello World",
},
}}
/>
## Options
| Name | Type | Default | Description |
| ------------------ | --------- | ------- | ----------------------------- |
| `enable_new_thing` | `boolean` | `false` | Enables the new functionality |
| `custom_text` | `string` | `""` | Custom text to display |
Edit website/sidebars.js and add your documentation to the appropriate category (maintain alphabetical order):
{
type: "category",
label: "🖥️ System", // or appropriate category
collapsed: true,
items: [
// ... other segments
"segments/system/new-feature",
// ... more segments
]
}
Update themes/schema.json in two places:
In the segment type enum, add your segment ID (maintain alphabetical order):
{
"enum": [
"angular",
// ... other types
"new-feature"
// ... more types
]
}
In the allOf array, add your segment's property schema (maintain alphabetical order):
{
"if": {
"properties": {
"type": { "const": "new-feature" }
}
},
"then": {
"title": "New Feature Segment",
"description": "https://ohmyposh.dev/docs/segments/system/new-feature",
"properties": {
"options": {
"properties": {
"enable_new_thing": {
"type": "boolean",
"title": "Enable New Thing",
"description": "Enables the new functionality",
"default": false
},
"custom_text": {
"type": "string",
"title": "Custom Text",
"description": "Custom text to display",
"default": ""
}
}
}
}
}
}
Create a test file src/segments/new_feature_test.go using table-driven tests:
package segments
import (
"testing"
"github.com/jandedobbeleer/oh-my-posh/src/segments/options"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
)
func TestNewFeature(t *testing.T) {
cases := []struct {
Case string
Template string
CustomText string
Expected string
}{
{Case: "default", CustomText: "", Expected: ""},
{Case: "custom text", CustomText: "Hello", Expected: "Hello"},
}
for _, tc := range cases {
t.Run(tc.Case, func(t *testing.T) {
env := &mock.Environment{}
props := options.Map{
CustomText: tc.CustomText,
}
segment := &NewFeature{}
segment.Init(props, env)
if !segment.Enabled() {
t.Error("Expected segment to be enabled")
}
if segment.Text != tc.Expected {
t.Errorf("Expected %s, got %s", tc.Expected, segment.Text)
}
})
}
}
Look at existing segment tests for more complex examples and inspiration.
Validate your implementation by building the project:
go build -v
Run your specific tests:
go test ./src/segments/new_feature_test.go
src/segments/[segment_id].gosrc/segments/[segment_id]_test.gowebsite/docs/segments/[category]/[segment-id].mdx### Alphabetical Ordering
Maintain alphabetical order in:init() gob registrations in segment_types.gosegment_types.gosegment_types.gothemes/schema.jsonallOf definitions in themes/schema.jsonsidebars.jsEnabled() logic focused and efficient.mdx extension for documentation filesOnce you've completed all steps:
go build -vgo test ./src/segments/[your_segment]_test.goBe patient during the review process! 🏎