Repository: ollama/ollama
Pull request: cmd: add ellipses to truncated show metadata

When a piece of information has been truncated in the show output an ellipses to indicate that more data has not been displayed.

Not communicating that the data had been truncated caused some confusion when troubleshooting an issue with model metadata.


Sample output:
```
❯ ollama show llama3.2-vision -v
# omitted unchanged fields here - Bruce
  Metadata
    mllama.vision.intermediate_layers_indices     [3 7 15 ...+2 more]        
    mllama.vision.max_num_tiles                   4                          
    mllama.vision.num_channels                    3                          
    mllama.vision.patch_size                      14                         
    mllama.vocab_size                             128256                     
    tokenizer.ggml.add_bos_token                  false                      
    tokenizer.ggml.add_eos_token                  false                      
    tokenizer.ggml.add_padding_token              false                      
    tokenizer.ggml.bos_token_id                   128000                     
    tokenizer.ggml.eos_token_id                   128009                     
    tokenizer.ggml.merges                         [Ġ Ġ ...+280146 more]      
    tokenizer.ggml.model                          gpt2                       
    tokenizer.ggml.padding_token_id               128004                     
    tokenizer.ggml.pre                            llama-bpe                  
    tokenizer.ggml.scores                         [0 1 2 ...+128254 more]    
    tokenizer.ggml.token_type                     [1 1 1 ...+128254 more]    
    tokenizer.ggml.tokens                         [! " # ...+128254 more]  
```

Changed files:
filename: cmd/cmd.go
patch: @@ -747,11 +747,38 @@ func showInfo(resp *api.ShowResponse, verbose bool, w io.Writer) error {
 				case float64:
 					v = fmt.Sprintf("%g", vData)
 				case []any:
-					n := 3
-					if len(vData) < n {
-						n = len(vData)
+					targetWidth := 10 // Small width where we are displaying the data in a column
+
+					var itemsToShow int
+					totalWidth := 1 // Start with 1 for opening bracket
+
+					// Find how many we can fit
+					for i := range vData {
+						itemStr := fmt.Sprintf("%v", vData[i])
+						width := runewidth.StringWidth(itemStr)
+
+						// Add separator width (", ") for all items except the first
+						if i > 0 {
+							width += 2
+						}
+
+						// Check if adding this item would exceed our width limit
+						if totalWidth+width > targetWidth && i > 0 {
+							break
+						}
+
+						totalWidth += width
+						itemsToShow++
+					}
+
+					// Format the output
+					if itemsToShow < len(vData) {
+						v = fmt.Sprintf("%v", vData[:itemsToShow])
+						v = strings.TrimSuffix(v, "]")
+						v += fmt.Sprintf(" ...+%d more]", len(vData)-itemsToShow)
+					} else {
+						v = fmt.Sprintf("%v", vData)
 					}
-					v = fmt.Sprintf("%v", vData[:n])
 				default:
 					v = fmt.Sprintf("%T", vData)
 				}
@@ -772,10 +799,19 @@ func showInfo(resp *api.ShowResponse, verbose bool, w io.Writer) error {
 
 	head := func(s string, n int) (rows [][]string) {
 		scanner := bufio.NewScanner(strings.NewReader(s))
-		for scanner.Scan() && (len(rows) < n || n < 0) {
-			if text := scanner.Text(); text != "" {
-				rows = append(rows, []string{"", strings.TrimSpace(text)})
+		count := 0
+		for scanner.Scan() {
+			text := strings.TrimSpace(scanner.Text())
+			if text == "" {
+				continue
 			}
+			count++
+			if n < 0 || count <= n {
+				rows = append(rows, []string{"", text})
+			}
+		}
+		if n >= 0 && count > n {
+			rows = append(rows, []string{"", "..."})
 		}
 		return
 	}

filename: cmd/cmd_test.go
patch: @@ -225,6 +225,7 @@ Weigh anchor!
   System
     You are a pirate!    
     Ahoy, matey!         
+    ...                  
 
 `
 		if diff := cmp.Diff(expect, b.String()); diff != "" {