Skip to main content

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, or web
  • 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:

  1. Open VS Code Chat (use the Chat icon in the sidebar or Command Palette: "Chat: Focus on Chat View")
  2. Type /segment and follow the prompts
  3. Provide your segment details when requested
  4. 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 in segment_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 in themes/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

Create a Pull Request

Once you've completed all steps:

  1. Verify everything builds: go build -v
  2. Run tests: go test ./src/segments/[your_segment]_test.go
  3. Check formatting: Ensure your code follows Go formatting standards
  4. Review checklist: All files created/updated as described above
  5. Create PR: Include a clear description of what your segment does

Be patient during the review process! 🏎