Add Segment
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.
Planning Your Segment
Before coding, define these key properties:
- Segment ID: A kebab-case identifier used in configs (e.g.,
new-feature
) - Go Type Name: PascalCase struct name for the code (e.g.,
NewFeature
) - Category: Choose from
cli
,cloud
,health
,languages
,music
,scm
,system
, orweb
- Description: A clear one-line explanation of what the segment does
- Properties: List of configurable properties with types and defaults
- Template: Default template string (e.g.,
{{ .Text }}
)
Automated Setup (VS Code)
If you're using VS Code, you can use the automated segment creation command in VS Code Chat:
- Open VS Code Chat (use the Chat icon in the sidebar or Command Palette: "Chat: Focus on Chat View")
- Type
/segment
and follow the prompts - Provide your segment details when requested
- The command will automatically create all necessary files and registrations
This 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.
Manual Setup Steps
Step 1: Create the Go Implementation
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/properties"
)
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 properties.Property = "enable_new_thing"
// CustomText sets custom display text
CustomText properties.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:
- Use UTF32 representation for icons (e.g.,
"\uEFF1"
) instead of the actual icons - Find icon codes at Nerd Fonts Cheat Sheet
- Keep the logic in
Enabled()
focused on data preparation and visibility determination
Step 2: Register Your Segment
Edit src/config/segment_types.go
to register your new segment:
Add Gob Registration
In the init()
function, add your segment to the gob registry (maintain alphabetical order):
gob.Register(&segments.NewFeature{})
Add Segment Constant
Add a constant for your segment type (maintain alphabetical order):
// NEWFEATURE displays new feature information
NEWFEATURE SegmentType = "new-feature"
Add to Segments Map
Register your segment in the Segments
map (maintain alphabetical order):
NEWFEATURE: func() SegmentWriter { return &segments.NewFeature{} },
Step 3: Create Documentation
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",
"properties": {
"enable_new_thing": true,
"custom_text": "Hello World"
}
}}/>
## Properties
| Name | Type | Description | Default |
| ---- | ---- | ----------- | ------- |
| `enable_new_thing` | `boolean` | Enables the new functionality | `false` |
| `custom_text` | `string` | Custom text to display | `""` |
Step 4: Update Sidebar Navigation
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
]
}
Step 5: Add JSON Schema Definition
Update themes/schema.json
in two places:
Add to Type Enum
In the segment type enum, add your segment ID (maintain alphabetical order):
{
"enum": [
"angular",
// ... other types
"new-feature",
// ... more types
]
}
Add Schema Definition
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": {
"properties": {
"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": ""
}
}
}
}
}
}
Step 6: Add Tests
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/properties"
"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 := properties.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.
Step 7: Build and Test
Validate your implementation by building the project:
go build -v
Run your specific tests:
go test ./src/segments/new_feature_test.go
Important Guidelines
File Organization
- Segment files:
src/segments/[segment_id].go
- Test files:
src/segments/[segment_id]_test.go
- Documentation:
website/docs/segments/[category]/[segment-id].mdx
### Alphabetical Ordering Maintain alphabetical order in: init()
gob registrations insegment_types.go
- Segment type constants in
segment_types.go
- Segments map entries in
segment_types.go
- Schema type enum in
themes/schema.json
- Schema
allOf
definitions inthemes/schema.json
- Sidebar navigation items in
sidebars.js
Code Quality
- Use meaningful property names and constants
- Include descriptive comments for properties
- Keep
Enabled()
logic focused and efficient - Use UTF32 codes for icons, not the actual icons
- Follow Go naming conventions (PascalCase for exported items)
Documentation Standards
- Use
.mdx
extension for documentation files - Include complete property tables with types, descriptions, and defaults
- Provide realistic sample configurations
- Keep line lengths under 120 characters
- Use proper headings and formatting
Resources
- Nerd Fonts Cheat Sheet - Find icon UTF32 codes
- Existing Tests - Examples for test patterns
- Table-Driven Tests - Go testing best practices
Create a Pull Request
Once you've completed all steps:
- Verify everything builds:
go build -v
- Run tests:
go test ./src/segments/[your_segment]_test.go
- Check formatting: Ensure your code follows Go formatting standards
- Review checklist: All files created/updated as described above
- Create PR: Include a clear description of what your segment does
Be patient during the review process! 🏎