> ## Documentation Index
> Fetch the complete documentation index at: https://ngquct-feat-ai-sql-walkthroughs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Code Style

> Swift conventions, tooling, naming, and file organization rules

# Code Style

`.swiftlint.yml` and `.swiftformat` are the source of truth. When in doubt, check those files.

## Core Rules

* **No comments.** Code must be self-explanatory through naming and structure. Do not add comments that describe what code does, reference tickets, or explain callers.
* **Early returns.** Use `guard` and early `return` instead of nested `if/else` blocks. Flatten control flow.

## Tools

```bash theme={null}
# Pre-commit gate (CI rejects warnings, so --strict is required)
swiftlint lint --strict

# Auto-fix lint issues
swiftlint --fix

# Format all code
swiftformat .

# Check formatting without applying
swiftformat --lint .
```

There is no SwiftLint build phase in the Xcode project. Lint runs manually and in CI.

## Formatting

| Rule         | Value                                             |
| ------------ | ------------------------------------------------- |
| Indentation  | 4 spaces (never tabs)                             |
| Line length  | 120 chars (SwiftLint warns at 180, errors at 300) |
| Braces       | K\&R (opening brace on same line)                 |
| Line endings | LF                                                |
| Semicolons   | None                                              |

Trailing commas are omitted by convention. Both tools have their trailing-comma rules disabled, so nothing enforces it.

## Naming

| Element                            | Convention        | Example                                            |
| ---------------------------------- | ----------------- | -------------------------------------------------- |
| Classes, Structs, Enums, Protocols | UpperCamelCase    | `DatabaseConnection`                               |
| Enum cases                         | lowerCamelCase    | `.postgresql`                                      |
| Functions, Variables, Constants    | lowerCamelCase    | `executeQuery()`, `maxRetryAttempts`               |
| Booleans                           | is/has/can prefix | `isConnected`, `hasValidCredentials`               |
| Factory methods                    | make prefix       | `makeConnection()`                                 |
| Acronyms                           | Treat as words    | `JsonEncoder` not `JSONEncoder` (except SDK types) |

## Access Control

Always explicit. Prefer the most restrictive level that works.

```swift theme={null}
// Specify on the extension, not individual members
public extension NSEvent {
    var semanticKeyCode: KeyCode? { ... }
}
```

## Imports

One alphabetical block, no blank lines between imports, one blank line after the last import. SwiftFormat enforces this (`--importgrouping alpha`, `blankLinesBetweenImports`, `blankLineAfterImports`).

```swift theme={null}
import AppKit
import CodeEditSourceEditor
import Foundation
import os
import TableProPluginKit

final class QueryRunner { ... }
```

## Safety

No force unwrapping (`!`) or force casting (`as!`). Use `guard let`, `if let`, `as?`.

```swift theme={null}
// Good
guard let connection = activeConnection else { return }

// Bad
let connection = activeConnection!
```

## Logging

OSLog only. Never `print()`.

```swift theme={null}
import os

private static let logger = Logger(subsystem: "com.TablePro", category: "DatabaseManager")
```

## Localization

* `String(localized:)` for user-facing strings in computed properties, AppKit code, alerts, error descriptions
* SwiftUI view literals (`Text("Save")`, `Button("Cancel")`) auto-localize
* Do not localize technical terms: font names, database types, SQL keywords, encoding names
* Never use `String(localized:)` with string interpolation. Use `String(format: String(localized: "Preview %@"), name)` instead.

## SwiftUI Patterns

* `@State` for local view state
* `@Observable` for viewmodels (Swift 5.9+)
* Property wrapper order: Environment, State, Binding, regular properties
* Extract large views into subviews

## Limits

| Metric                | Warning    | Error      |
| --------------------- | ---------- | ---------- |
| File length           | 1200 lines | 1800 lines |
| Type body             | 1100 lines | 1500 lines |
| Function body         | 160 lines  | 250 lines  |
| Cyclomatic complexity | 40         | 60         |

When approaching these limits, extract into extension files:

<Tree>
  <Tree.File name="MainContentCoordinator.swift" />

  <Tree.Folder name="Extensions" defaultOpen>
    <Tree.File name="MainContentCoordinator+RowOperations.swift" />

    <Tree.File name="MainContentCoordinator+Pagination.swift" />

    <Tree.File name="MainContentCoordinator+Filtering.swift" />
  </Tree.Folder>
</Tree>

Group by domain logic, not arbitrary line counts.
