diff --git a/example_test.go b/example_test.go
index be3cd12..4e6372f 100644
--- a/example_test.go
+++ b/example_test.go
@@ -235,7 +235,8 @@ func Example_helpTextForSubcommand() {
 	// Positional arguments:
 	//   ITEM                   item to fetch
 	//
-	// Options:
+	// Global options:
+	//   --verbose
 	//   --help, -h             display this help and exit
 }
 
diff --git a/usage.go b/usage.go
index 7ee68da..db43dd1 100644
--- a/usage.go
+++ b/usage.go
@@ -27,7 +27,11 @@ func (p *Parser) failWithCommand(msg string, cmd *command) {
 
 // WriteUsage writes usage information to the given writer
 func (p *Parser) WriteUsage(w io.Writer) {
-	p.writeUsageForCommand(w, p.cmd)
+	cmd := p.cmd
+	if p.lastCmd != nil {
+		cmd = p.lastCmd
+	}
+	p.writeUsageForCommand(w, cmd)
 }
 
 // writeUsageForCommand writes usage information for the given subcommand
@@ -116,7 +120,11 @@ func printTwoCols(w io.Writer, left, help string, defaultVal string) {
 
 // WriteHelp writes the usage string followed by the full help string for each option
 func (p *Parser) WriteHelp(w io.Writer) {
-	p.writeHelpForCommand(w, p.cmd)
+	cmd := p.cmd
+	if p.lastCmd != nil {
+		cmd = p.lastCmd
+	}
+	p.writeHelpForCommand(w, cmd)
 }
 
 // writeHelp writes the usage string for the given subcommand
@@ -144,9 +152,27 @@ func (p *Parser) writeHelpForCommand(w io.Writer, cmd *command) {
 	}
 
 	// write the list of options
-	fmt.Fprint(w, "\nOptions:\n")
-	for _, spec := range options {
-		p.printOption(w, spec)
+	if len(options) > 0 || cmd.parent == nil {
+		fmt.Fprint(w, "\nOptions:\n")
+		for _, spec := range options {
+			p.printOption(w, spec)
+		}
+	}
+
+	// obtain a flattened list of options from all ancestors
+	var globals []*spec
+	ancestor := cmd.parent
+	for ancestor != nil {
+		globals = append(globals, ancestor.specs...)
+		ancestor = ancestor.parent
+	}
+
+	// write the list of global options
+	if len(globals) > 0 {
+		fmt.Fprint(w, "\nGlobal options:\n")
+		for _, spec := range globals {
+			p.printOption(w, spec)
+		}
 	}
 
 	// write the list of built in options
diff --git a/usage_test.go b/usage_test.go
index d9d33f0..31b439b 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -266,8 +266,45 @@ Options:
 	p, err := NewParser(Config{}, &args)
 	require.NoError(t, err)
 
-	os.Args[0] = "example"
 	var help bytes.Buffer
 	p.WriteHelp(&help)
 	assert.Equal(t, expectedHelp, help.String())
 }
+
+func TestUsagWithNestedSubcommands(t *testing.T) {
+	expectedHelp := `Usage: example child nested [--enable] OUTPUT
+
+Positional arguments:
+  OUTPUT
+
+Options:
+  --enable
+
+Global options:
+  --values VALUES        Values
+  --verbose, -v          verbosity level
+  --help, -h             display this help and exit
+`
+
+	var args struct {
+		Verbose bool `arg:"-v" help:"verbosity level"`
+		Child   *struct {
+			Values []float64 `help:"Values"`
+			Nested *struct {
+				Enable bool
+				Output string `arg:"positional,required"`
+			} `arg:"subcommand:nested"`
+		} `arg:"subcommand:child"`
+	}
+
+	os.Args[0] = "example"
+	p, err := NewParser(Config{}, &args)
+	require.NoError(t, err)
+
+	_ = p.Parse([]string{"child", "nested", "value"})
+
+	var help bytes.Buffer
+	p.WriteHelp(&help)
+	fmt.Println(help.String())
+	assert.Equal(t, expectedHelp, help.String())
+}