If you're interested in making a contribution, this document aims to describe the most important components of iTerm2's source.
You may also want to read HowToBuild and HowToContribute.
The key classes are PseudoTerminal, PTYTab, PTYSession, SessionView, PTYTextView, VT100Screen, VT100Grid, LineBuffer/LineBlock, and VT100Terminal (and related classes VT100Token and VT100*Parser).
PseudoTerminal is a window controller and is 1:1 with windows. It has a tabview, in which most of the content is displayed), and also contains links to the toolbar. It's the delegate for PSMTabBarControl, which runs the tab bar UI. It's also the NSWindow delegate. It has the following responsibilities:
- Manage window attributes (frame, whether to draw a border, controlling the appearance of the tab bar, and ensuring subviews are properly positioned).
- Managing the set of sessions to which input is broadcast
- Managing the toolbelt (which appears in either a drawer or a subview, depending on window style)
- Assisting with drag-drop operations of tabs and sessions.
- Managing the window title.
- Handling certain events, such as pinch-to-zoom to change font size and routing swipes.
- Managing and providing accessors to the tabs.
- Receiving and handling commands from the menu bar that go to the first responder (e.g., close session).
- Creating and restoring the window-specific parts of saved arrangements and delegating tab/session attributes to other classes, and helping to draw previews of saved arrangements in prefs>arrangements.
- Handling window delegate and window controller messages, such as confirming that a window should close; setting the frame when zooming; hiding the hotkey window when it loses first-responder status; ensuring the proper windows are dimmed; snapping the window size to a multiple of character size; etc.
- Updating window frame when the number of screens or screen configuration changes.
- Interfacing with other tmux-integration classes for window-related activities (such as saving window frames on the server, managing layout changes, etc.)
- Routing various changes down to the tab or session level (such as changes to scrollbar style)
- Toggling fullscreen mode (including traditional and native [aka Lion] mode)
- Routing and managing most instant-replay-related events.
- Managing popup windows (paste history, autocomplete, command history)
- Providing interfaces for Applescript to manipulate tabs (which are unfortunately called sessions for historical reasons)
PTYTab is the "identifier" for an NSTabViewItem. It is 1:1 with tabs. It contains a collection of PTYSession objects. It has a tree called root whose intermediate nodes are NSSplitView and whose leaves are SessionView. The tree has only one level if there are no split panes. It is a tree because an NSSplitView is oriented either horizontally or vertically and iTerm2 allows nesting of split panes in either direction. PTYTab is the delegate for the NSSplitViews. Its responsibilities are:
- Managing navigation among split panes
- Managing the frames of subviews
- Managing the tree of subviews (nested PTYSplitView's with SessionViews hanging off them)
- Managing the tab title, bell icon, label color, and activity indicator in the tab bar (via methods that are key-value observed by the tab library)
- Managing the "current" (or active) session, including responding to user navigation actions
- Saving and restoring saved arrangements (at the tab level) and delegating same to each PTYSession
- Provides linkage between window and sessions for instant replay
- Is the delegate of PTYSplitView (a subview of NSSplitView). This is complicated.
- Produces a snapshot of the view hierarchy
- Figures the size of the corresponding tmux window in tmux integration mode
- Replicates the tmux pane structure in tmux integration mode
- Handles maximizing split panes
PTYSession is a sort of glue object that is 1:1 with sessions. It owns the other objects that are 1:1 with sessions (PTYTextView, SessionView, VT100Screen, VT100Terminal). Its responsibilities are:
- It runs a timer that causes PTYTextView to redraw periodically.
- Manages instant replay directly.
- Creates and restores saved arrangements at the session level
- Prompts before closing a session, if necessary
- Determines the command and working directory for sessions
- Shows the short-lived session warning
- Interfaces with PTYTask for reading, writing, and ending tasks.
- Converts keypresses to bound actions or dispatches them to VT100Output to generate the proper output
- Connects input to triggers
- Posts notifications for sessions that ended, idle, bell-ringing, and activity.
- Keeps a copy of the Profile and updates itself and child objects when the profile changes
- When Edit Current Session is used to change preferences, PTYSession remembers which prefs are customized and which are shared with the original profile.
- Manages session titles
- Defines the environment vars that are set
- Runs the anti-idle timer
- Handles session logging
- Handles changing profile and pushing modified settings up to the original profile
- Deals with details of font changing
- May act as a gateway to tmux integration
- Navigates marks/notes
- Provides applescript support at the session level
SessionView is an NSView subclass that wraps PTYTextView. In reality, there are several views between SessionView and PTYTextView (there's a scrollview subclass that doesn't do much, and within that is a TextViewWrapper that adds a margin to the top, and within that is the SessionView). SessionView controls dimming of inactive panes.
PTYTextView is an NSView subclass. It is responsible for drawing text and responding to mouse clicks, handling selection, and a potpourri of other things. It is an extremely tall view--as tall as the screen plus the scrollback buffer. It's also flipped, which means that y=0 is at the bottom of the window. This causes lots of confusion but makes keeping the visible frame locked at the bottom very simple.
VT100Screen is responsible for an N x M matrix of characters exactly the size of the visible region. It owns the cursor and manipulates screen content. It has a LineBuffer and transfers lines of text into it as the scroll off, or pulls them out when the window grows.
VT100Terminal: Implements the VT100/xterm/whatever we really do line protocol. It sends commands to VT100Screen, mostly.
LineBuffer is a scrollback buffer. It is an array of LineBlocks. A LineBlock is a big memory buffer plus an index into it. The index converts a line number into an offset into the memory buffer. The index can also be used to infer the length of one of these lines. The lines in the memory buffer do not take the width of the screen into account--they are as long as what was originally received from the host. LineBuffer is responsible for figuring out where lines are after wrapping them to the screen's width. It is also like a "stack" in that you can "pop" a portion of a line from the end (used when a window becomes taller, for instance). LineBuffer also implements part of the Find functionality. It exposes a way of referring to a location in the scrollback history via an integer, and offers conversion functions between that and an (x,y) coordinate for a given wrapping width.
Some less important but noteworthy classes are:
- ProfileModel: Stores the collection of address book entrees (née bookmarks)
- DVRxxx: Implements instant replay
- ITAddressBookMgr: Handles importing address books, bonjour
- iTermController: App-wide glue, including hotkey support
- iTermApplication: Overrides sendEvent, the lowest-level event handler, to do various high-priority things when when keys are pressed.
- iTermExpose, GlobalSearch: Implements Exposé All Tabs
- iTermKeyBindingMgr: Maintains key binding relationships for per-address book entry and global key bindings
- Popup: The infrastructure for popups, as implemented by Autocomplete and PasteboardHistory
- PreferencePanel: Handles all the preferences UI
- ProcessCache: Periodically polls the OS, in a separate thread, to get foreground job names that are displayed in tab/window titles.
- PTYTask: Implements a select() loop in another thread, fork(), exec(), wait(), and tty setup.
- ScreenChar: Utility functions for screen_char_t, the fundamental unit of a screen character.