News

Sublime Text 4

May 21, 2021 by Benjamin Schaaf

The first stable release of Sublime Text 4 has finally arrived! We've worked hard on providing improvements without losing focus on what makes Sublime Text great. There are some new major features that we hope will significantly improve your workflow and a countless number of minor improvements across the board.

A huge thanks goes out to all the beta testers on discord and all the contributors to our packages.

Download Sublime Text 4

License Changes

Sublime Text license keys are no longer tied to a single major version, instead they are now valid for all updates within 3 years of purchase. After that, you will still have full access to every version of Sublime Text released within the 3 year window, but newer builds will required a license upgrade. These are the same license terms we use for Sublime Merge, and they allow us to deliver more frequent and exciting updates as soon as they're ready, without having to roll them into a new major version.

Tab Multi-Select

File tabs have been enhanced to make split views effortless, with support throughout the interface and built-in commands. The side bar, tab bar, Goto Anything, Goto Definition, auto complete and more have all been tweaked to make code navigation easier and more intuitive than ever.

Apple Silicon and Linux ARM64

Sublime Text for Mac now includes native support for Apple Silicon processors. Linux ARM64 builds are also available for devices like the Raspberry Pi.

Refreshed UI

The Default and Adaptive themes have been refreshed with new tab styles and inactive pane dimming. Themes and Color Schemes support auto dark-mode switching. The Adaptive theme on Windows and Linux now features custom title bars.

Context-Aware Auto Complete

The auto complete engine has been rewritten to provide smart completions based on existing code in a project. Suggestions are also augmented with info about their kind, and provide links to definitions.

TypeScript, JSX and TSX Support

Support for one of the most popular new programming languages is now shipped by default. Utilize all of the smart syntax-based features of Sublime Text within the modern JavaScript ecosystem.

Superpowered Syntax Definitions

The syntax highlighting engine has been significantly improved, with new features like handling non-deterministic grammars, multi-line constructs, lazy embeds and syntax inheritance. Memory usage has been reduced, and load times are faster than ever.

GPU Rendering

Sublime Text can now utilize your GPU on Linux, Mac and Windows when rendering the interface. This results in a fluid UI all the way up to 8K resolutions, all while using less power than before.

A single frame being rendered. See our blogpost on OpenGL rendering.

Updated Python API

The Sublime Text API has been updated to Python 3.8, while keeping backwards compatibility with packages built for Sublime Text 3. The API has been significantly expanded, adding features that allow plugins like LSP to work better than ever. Read the revamped documentation here.

Compatibility

Sublime Text 4 is fully compatible with version 3. It will pickup your session and configuration automatically. If you'd prefer however, it is possible to keep things separate.


Download Sublime Text 4


Full Changelog

GPU Rendering

  • New hardware_acceleration setting will composite the UI on the GPU
  • By default, GPU rendering is enabled on Mac, and disabled on Windows and Linux
  • Details about the active GPU will be displayed in the Console

Context-aware Auto Complete

  • The auto complete engine now suggests completions based on patterns in existing code
  • Uses the entire project as a source, instead of just the current view
  • Plugins may specify symbol kind info to be displayed in suggestions list

Tab Multi-Select

  • Multiple tabs can be selected using ctrl/cmd, their contents will be shown side-by-side
  • Selecting multiple files from the sidebar will also preview them simultaneously
  • Included themes have a tab connector joining the active sheet and tab when using sheet multi-select
  • The sidebar can now select multiple files using alt
  • Goto Anything allows opening tabs side-by-side using ctrl/cmd
  • The Definition popup has a dedicated button for opening files side-by-side
  • Multiple tabs can also be selected from the tab dropdown
  • The menu Selection/Tab Selection contains various options for manipulating tab multi-select
  • File/New View into File has been replaced by File/Split View using multi-select

Python 3.8 API

  • Added a Python 3.8 API environment for plugins
  • Plugins can choose Python version via .python-version file in plugin folder
  • Existing plugins are fully supported via legacy Python 3.3 API
  • Many API improvements and additions - see API section for more details

Goto Symbol

  • Goto Symbol in Project is now significantly faster on huge projects
  • Icons are now shown next to symbols, indicating the symbol kind
  • Symbols with 3 characters or less are now indexed

Syntax Definitions

  • Added out of the box support for TypeScript, JSX and TSX - thanks to Thomas Smith
  • Added ability to "branch" within syntax definitions, for non-deterministic or multi-line constructs
  • Many syntax highlighting improvements, including significant improvements to:
  • Significantly improved load times, match times and reduced cache size on disk
  • embed is now lazy loaded, resulting in much higher performance for syntaxes like markdown
  • Added branch and fail for non-deterministic parsing
  • Added version: 2 to fix edge cases while retaining backwards compatibility
  • Added extends to inherit from another syntax definition. Multiple inheritance is supported, provided all parents have the same base syntax
  • Added hidden_extensions
  • Allow using pop alongside push/set/embed/branch
  • Fixed a performance issue with bounded repeats in regular expressions
  • Syntax tests can now assert that reindent is working as expected
  • Syntax tests can now assert that symbols are indexed
  • Prevent infinite include loops via with_prototype
  • Fixed a number of scope related bugs
  • Fixed some regex capture related bugs
  • Added more information to the Show Scope Name popup

OS Compatibility

  • The following operating systems are no longer supported as a result of adding Python 3.8:
    • OS X 10.7
    • OS X 10.8
    • Windows XP
    • Windows Vista

Platform Integration

  • Added automatic dark/light theme and color scheme switching, based on OS theme changes
  • subl - can now be used to read from stdin on all platforms
  • Windows will remember their Virtual Desktop/Space/Workspace, controlled by the remember_workspace setting
  • Scroll bars now follow platform conventions when clicking on them. Configurable using Scroll Bar.sublime-mousemap
  • Mac: Releases use universal binaries with Apple Silicon support
  • Mac: Updated icon to follow macOS 11 style
  • Mac: Windows will now stay maximized when using Mac window tabs
  • Mac: Fix various issues with the wrong cursor being used
  • Linux: ARM64 builds are now available
  • Linux: Text drag and drop is now supported
  • Linux: Added proper support for Wayland
  • Linux: Touch screen events are now handled
  • Linux: Better support for copy+paste with other applications that don't support utf8 text
  • Linux: Native file dialogs like those for KDE will be used when configured
  • Windows: IME preview and multi-select support
  • Windows, Linux: Added support for custom title bars
  • Windows, Linux: Use vsync for animations instead of a fixed 60hz
  • Mac, Linux: Improved compatibility with some keyboard layouts

Application Behavior

  • Added Safe Mode, to simulate a clean install. Enabled by passing --safe-mode on the command line or holding shift+alt/option at startup on Windows/macOS respectively
  • Added Help/Report a Bug to link to our public issue tracker
  • Added options to hot_exit setting to control behavior when the last window is closed
  • Fixed a possible case where an update loses the current session
  • Settings containing a UTF-8 BOM will no longer fail to load
  • Added support for previewing TGA and PSD images
  • Added close_deleted_files setting to control behavior of session restoration when files have been deleted on disk
  • Popup windows now use virtual windows for improved performance
  • Improved performance when loading files with very long lines
  • Improved rendering performance on very long lines
  • Improved performance with large session files
  • Data directories have dropped the "3", though if a "3" directory still exists it will be used
  • Mac: Quick Switch Project now works without any windows open
  • Mac, Linux: The cache and index are now located in the proper location (~/.cache and ~/Library/Caches respectively)

Auto Complete

  • Typing the full tab trigger of a snippet will move it to the top of the results
  • Manually typing in the only available completion will hide the auto complete popup
  • .sublime-completion files can now specify annotation, kind and details
  • Ranking quality improvements
  • Improved behavior of completions starting with non-word characters
  • auto_complete_trailing_symbols is now disabled by default
  • cancelCompletion will no longer prevent manual invocation
  • Added the auto_complete_when_likely setting
  • Added auto_complete_preserve_order setting
  • Added auto_complete_include_snippets_when_typing setting
  • Added auto_complete_use_index setting
  • Added auto_complete_use_history setting to control if previous choices are automatically selected
  • Running the auto_complete command when auto complete is already showing will re-query plugins for results
  • auto_complete_selector now applies to the position before the just-typed in character, matching auto_complete_triggers

Input Handling

  • Modifier key taps can now be used as part of a key binding. For example, ["ctrl", "ctrl"] will trigger when Ctrl is pressed twice without pressing any other keys in between
  • Linux: AltGr can now be used in key bindings via altgr
  • Linux: Added a workaround for a touchscreen driver bug, which would cause right click and mouse scrolling to stop working
  • Linux: When the menu is hidden, pressing alt will show it
  • Mac: Fix Pinyin input
  • Mac: Keypad keys can now be bound to as expected
  • Mac: Added key bindings for macOS application tabs
  • Windows, Linux: Hide mouse cursor when typing. Controlled via hide_pointer_while_typing setting
  • Windows, Linux: Fixed being unable to bind Ctrl+Break

Editor Control

  • Added File/Print, which prints via a browser
  • Added Edit/Copy as HTML
  • Build systems now use new annotations functionality instead of phantoms, reducing re-flow
  • Undo history is preserved in the session
  • Comments and layout are preserved when programmatically editing preferences
  • Caret blinking is disabled by default. Set caret_style setting to smooth for previous behavior
  • Improved automatic indentation detection
  • Added relative line numbers, controlled by the relative_line_numbers setting
  • Added setting scroll_context_lines
  • Added setting hide_pointer_while_typing
  • Added setting control_character_style
  • Added Project/Recent/Remove Deleted
  • Added chain command to run multiple commands in series
  • switch_file command now handles filenames with compound extensions
  • The scroll_past_end setting now supports customizing the scroll distance using numbers from 0.0 to 1.0
  • Double-clicking a semi-transient sheet's tab will now fully open the sheet
  • trim_trailing_white_space_on_save can now be set to "not_on_caret"
  • trim_trailing_white_space_on_save now trims only newly inserted trailing whitespace by default. Controlled via trim_only_modified_white_space setting
  • Expanded draw_white_space setting, supporting leading and trailing white space
  • Unicode white space characters, such as the zero width no-break space, are now drawn as hex values. Controlled via draw_unicode_white_space setting
  • Fixed spelling correction to support languages with upper case characters after start of word
  • Added commands to simplify customizing the active theme or color scheme
  • Quick Switch Project will open the selected project in a new window if Ctrl (Cmd on Mac) is held down
  • Added wrap_width_style preference
  • Added console_max_history_lines
  • Added additional settings to control the status bar: show_sidebar_button, show_indentation and show_syntax
  • Console now uses Python syntax highlighting by default
  • Added Central European (Mac) encoding support
  • Key Bindings: Join Lines is now on Ctrl+Shift+J / Cmd+Shift+J
  • Key Bindings: Expand Selection to Indentation is no longer bound by default
  • Key Bindings: Ctrl+J / Cmd+J is now used as a prefix for sequential key bindings, similar to Ctrl+K / Cmd+K
  • Code Folding: fixed some edge-case incorrect behaviors
  • Linux: Added support for alternate font weight names
  • Linux: Selection is no longer cleared when another application makes a selection
  • Linux: Added Ctrl+Space to trigger Auto Complete
  • Linux, Windows: Added Alt+Shift+Left Mouse Button as an alternative column selection binding
  • Linux, Windows: Added Shift+F10 key binding to open the context menu

Text Commands

  • Macros now record Find commands
  • Reworked Jump Back and Jump Forward commands
  • Improved behavior of Wrap Paragraph
  • Improved behavior of Swap Lines
  • Added Revert Diff Hunk
  • Added Selection/Expand Selection as a general mechanism to expand the selection
  • Selection/Split into Lines will now split a selection into words if the selection doesn't contain any newlines
  • Show a sum in the status bar when there are multiple selections and all of them are numbers
  • set_file_type command now accepts "scope:" prefixed syntax names
  • Fixed sort_lines replacing unicode newlines with regular ones

Snippets

  • Added auto_complete_include_snippets setting, for disabling auto complete integration
  • Added ignored_snippets setting, for disabling default snippets

Indexing (Goto Definition)

  • Files ignored by .gitignore are not indexed by default. Controlled via index_exclude_gitignore setting
  • Files without known extensions are no longer indexed by default. Controlled via index_skip_unknown_extensions setting
  • Improved behavior with constantly changing files
  • Significantly improved load times

Files and Folders

  • Saving files is now asynchronous
  • Improved performance when adding directories with extreme amounts of files
  • When save_on_focus_lost is enabled, closing an unsaved file will save and close it, instead of prompting to save
  • Improved behavior of save_on_focus_lost in conjunction with administrator owned files
  • Added reload_file_on_change setting to control if files are automatically reloaded or not
  • folder_exclude_patterns and folder_include_patterns now support project-relative paths, by starting the path with //
  • Folders in the sidebar can be recursively expanded via alt+arrow key
  • Added preview_on_click setting to support only previewing files on left click
  • Windows: Fixed Open Containing Folder for UNC paths
  • Windows: Fixed Save dialog not showing for new files with control characters on the first line
  • Windows: Fixed Ctrl+Backspace inserting a DEL character when a dialog is open in the background
  • Linux: Fix recreated directories not working correctly with file change monitoring
  • Linux: Recursively expanding and collapsing sidebar folders now works with alt or super

Find

  • Find results are highlighted on the scroll bar, controlled by highlight_find_results_in_scrollbar
  • Find in Selection now highlights the area that will be searched
  • Commands can now be run without the find panel having input focus
  • Fix keypad enter not working in find panel
  • Improved find history behavior
  • Find: Various performance improvements with large files using graceful degradation
  • Find: Fixed adjacent matches being skipped when find in selection is in use
  • Find: Fixed find in selection option not being cleared when changing tabs
  • Find: Selection will no longer be reset after Find All is used when finding in selection
  • Find: Results are now properly highlighted on Find All when close_find_after_find_all is turned off
  • Find in Files: Improved performance with large numbers of matches
  • Find in Files: Can now filter by .gitignore
  • Find in Files: Added Preserve Case option for replacements
  • Find in Files: Fix not recursing into directories on networked file systems
  • Find in Files: Hide rulers by default in find results
  • Find in Files: Added Find/Cancel Find in Files menu item
  • Find in Files: Binary file patterns are applied when an explicit folder is given
  • Find in Files: Using "Find in Folder…" from the sidebar context menu will apply project file filters
  • Find in Files: Added close_find_after_find_all preference
  • Find in Files: Added close_find_after_replace_all preference

UI

  • Changed default color scheme to Mariana
  • Added Default Dark theme
  • Added themed_title_bar setting
  • Changed file tab style, adding file_tab_style setting
  • Goto Symbol shows more information about symbols
  • Definitions hover popup shows more information about symbols
  • Sheets without input focus are now dimmed when using included themes
  • Added a New Tab button in the tab bar, and hide_new_tab_button setting
  • Added show_tab_close_buttons_on_left setting
  • Added highlight_gutter and highlight_line_number settings
  • Added the ability to auto hide the menu, tabs, and status bar when typing. See auto_hide_menu and related settings
  • Window title bar can be controlled by show_rel_path and show_project_first settings
  • Tab context menu now includes Close Unmodified Files and Close Deleted Files entries
  • Side bar row highlights now properly reflect the selected tabs
  • Color Schemes: Added glow font option
  • Color Schemes: Added support for the underline font style
  • Color Schemes: Added new property, inactive_selection_border
  • Color Schemes: Slightly darkened the background of Mariana
  • Color Schemes: Added support for stippled_underline and squiggly_underline
  • Color Schemes: .hidden-tmTheme files are now supported by the .sublime-color-scheme convertor
  • Themes: Included themes use variables extensively, making customization simpler
  • Themes: Added style property for title_bar element, for better integration with OS "dark modes"
  • Themes: The tree_row for the file with input focus now gets the attribute highlighted
  • Themes: The settings key now supports objects, with keys being settings and values being a boolean, string or array of strings
  • Themes: Added sheet_contents class to text, image and HTML sheets
  • Themes: Added the background_modifier property for sheet_contents
  • Themes: Added a number of new attributes to tab_control for richer tab theming
  • Themes: The highlighted attribute is only applied to the most recently active sheet, rather that the most recently active sheet in each group
  • Themes: tab_control and sheet_contents classes now synchronize their highlighted and hover attributes
  • Themes: tooltip controls now support animations to their opacity
  • Linux: Show sequential key bindings in the menu
  • Linux: Fixed context menu position being slightly offset

Spell Checking

  • Updated dictionaries
  • Added support for non-utf8 dictionaries
  • Updated Hunspell for improved suggestions
  • System dictionaries are now available on Linux
  • Dictionaries in ~/Library/Spelling are now available on Mac

Rendering

  • Properly query glyph extents in order to avoid cutting off large glyphs
  • Windows, Linux: Added support for per-display subpixel ordering
  • Mac: Improved window resize performance
  • Windows: Fixed rendering bug where other applications could cause persistent artifacts via window animations
  • Windows: Add support for color emoji

API

  • Improved coverage of plugin profiling
  • The cProfile module is now included on Linux
  • Added HTML sheets, which can be created via window.new_html_sheet()
  • repr now works as expected
  • Updated OpenSSL to 1.1.1j
  • .sublime-commands files now support filtering commands via the "platform" key
  • Minihtml now handles list-style-type CSS property - circle, square and disc
  • Minihtml now processes subl: links, running them as commands
  • Minihtml now supports white-space: nowrap
  • Improved minihtml rendering performance
  • EventListener has many new features and bug fixes
    • on_query_completions() can now
      • Return suggestions asynchronously
      • Return command completions
      • Include symbol kind information
    • New: on_init() is called once with list of views opened before plugin was loaded
    • New: on_exit() is called immediately before plugin_host exits, after API is shut down
    • New: on_text_changed() and on_text_changed_async() provide detailed modification info
    • New methods:
      • on_reload()
      • on_revert()
      • on_new_window()
      • on_new_window_async()
      • on_pre_close_window()
      • on_pre_move()
      • on_post_move()
      • on_post_move_async()
      • on_new_project()
      • on_new_project_async()
      • on_load_project()
      • on_load_project_async()
      • on_pre_save_project()
      • on_post_save_project()
      • on_post_save_project_async()
      • on_pre_close_project()
      • on_associate_buffer()
    • Fixed on_selection_modified() to not be called twice when left clicking
    • Fixed on_selection_modified() begin called on non-selection state changes
  • New TextChangeListener for getting callbacks when a text buffer is changed
    • Can be dynamically bound to a Buffer using TextChangeListener.attach and TextChangeListener.detach
    • Methods:
      • on_text_changed()
      • on_text_changed_async()
      • on_revert()
      • on_revert_async()
      • on_reload()
      • on_reload_async()
  • Sheet has some new methods:
    • file_name()
    • group()
    • close()
    • is_semi_transient()
    • Sheet.is_transient
  • View has a number of changes and improvements
    • Fixed newly created views not having a valid viewport before being returned to the API
    • add_regions() now has an annotations parameter, to allow adding a per-region annotation to the buffer. The exec command uses this API for build errors
    • add_regions() calls that add an underline now have that underline applied to whitespace characters
    • show() now takes keep_to_left and animate parameters
    • text_point() and related functions now accept a clamp_column parameter
    • Added "glow" to style_for_scope()
    • Added View.rowcol_utf8(), View.rowcol_utf16(), View.text_point_utf8() and View.text_point_utf16()
    • Added sublime.KEEP_ON_SELECTION_MODIFIED, which can be passed to show_popup()
    • New: element() returns a string describing widget views (find input, quick panel input, etc)
    • New: assign_syntax() sets the syntax used in a view, supports Syntax objects, paths and scope selectors
    • New: syntax() returns the currently set Syntax
    • New: clones()
    • New: sheet() and sheet_id()
    • New: export_to_html()
  • Window has some changes and improvements:
    • show_quick_panel now accepts placeholder text, via the placeholder argument
    • Added sublime.CLEAR_TO_RIGHT and sublime.SEMI_TRANSIENT for use with open_file()
    • Added the flag sublime.REPLACE_MRU for use with open_file(). When multiple sheets are selected, this flag will cause the opened file to replace the most recently used sheet with the file being opened
    • Added the flag sublime.WANT_EVENT for use with show_quick_panel(). This will pass an event dict to the on_select callback. The dict will contain the key modifier_keys, which will be a dict that may contain zero or more of the keys: primary, ctrl, super, alt, altgr
    • open_file now accepts sublime.ADD_TO_SELECTION as a flag
    • New: selected_sheets(), selected_sheets_in_group() and select_sheets()
    • New: workspace_file_name()
    • New: bring_to_front()
  • sublime.ok_cancel_dialog() and sublime.yes_no_cancel_dialog() now accept an optional title parameter
  • Added sublime.open_dialog, sublime.save_dialog and sublime.select_folder_dialog
  • Syntax definitions can be queried via sublime.list_syntaxes(), sublime.find_syntax(), sublime.syntax_from_path(), sublime.find_syntax_by_name(), sublime.find_syntax_by_scope(), and sublime.find_syntax_for_file(). They return Syntax objects
  • Improved sys.stdout to extend io.TextIOBase
  • sublime.executable_path(), sublime.packages_path(), sublime.installed_packages_path() and sublime.cache_path() may now be called at import time
  • Added sublime.SymbolRegion and sublime.SymbolLocation with corresponding methods on View and Window
  • Fix a bug with popup being stuck open when a popup is shown in the hide event handler of another popup
  • Added open_project_or_workspace command
  • append command has new, optional disable_tab_translation argument
  • Added modifier_keys to event dicts when commands are invoked via a menu
  • Added sublime.DYNAMIC_COMPLETIONS. on_query_completions() can return this flag to indicate that completion results should be re-queried as the user types
  • Added sublime.INHIBIT_REORDER. Returned by on_query_competions()
  • CompletionItem now accepts a details parameter, which can include basic HTML
  • CommandInputHandler now has an initial_selection() method
  • Added Region.to_tuple and Phantom.to_tuple
  • Fixed ViewEventListener.on_load_async() sometimes not being called
  • Added sublime.QuickPanelItem() with support for kind info, annotations and basic minihtml
  • Plugins may now add selections to the Jump Back history list via the add_jump_record command
  • Plugins may suppress selections from the Jump Back history list via the jump_ignore_selection region
  • Plugins may now disable the default HTML and CSS completions
  • Added Buffer.id() and Buffer.file_name()
  • The TextInputHandler and ListInputHandler classes may define a method want_event() that returns True to receive an extra parameter, an event dict, when the validate() and confirm() methods are called. The dict will contain the key modifier_keys, which will be a dict that may contain zero or more of the keys: primary, ctrl, super, alt, altgr
  • Add sublime.ui_info() for high-level information about the UI
  • Popups will be properly positioned when displayed near the right-hand side of the editor
  • Popups near the right-hand side of the editor with wrapped lines will now be properly sized
  • Added ListInputItem so that ListInputHandler objects can provide kind info, annotations and details
  • Improvements to the API, applied to the new Python 3.8 environment only:
    • bool(sublime.Selection()) will return False when len() == 0
    • sublime.load_binary_resource() now returns bytes instead of bytearray
    • Added Selection.__iter__()
    • Added Region.__iter__()
    • Added Region.__contains__()
    • Added Settings.to_dict()
    • Settings can now be treated like a dict
    • Plugins starting with _ will be ignored, __all__ global will be respected
    • Events won't be reported until plugin_loaded() has been called
    • .pyc files can now be imported when contained within .sublime-package files, although they will not be scanned for plugins
  • The certifi Python package is preinstalled
  • Significant performance improvements when rapidly printing to the Console
  • Added sublime.log_control_tree(). When enabled, clicking with ctrl+alt will log the control tree under the mouse to the console
  • Added sublime.log_fps(). When enabled, the render times are tracked and logged
  • Added logging status functions:
    • sublime.get_log_commands()
    • sublime.get_log_input()
    • sublime.get_log_build_systems()
    • sublime.get_log_result_regex()
    • sublime.get_log_indexing()
    • sublime.get_log_fps()
    • sublime.get_log_control_tree()
  • Logging functions are now toggle when no argument is passed:
    • sublime.log_commands()
    • sublime.log_input()
    • sublime.log_build_systems()
    • sublime.log_result_regex()
    • sublime.log_indexing()
    • sublime.log_fps()
    • sublime.log_control_tree()
  • Backwards Compatibility Break: The event parameter passed to commands when a minihtml link is clicked changed from a two-element list to a dict with the keys x and y

Faster Rendering Using Hardware Acceleration

April 28, 2021 by Benjamin Schaaf

At Sublime HQ we like to put in extra effort for performance, which is why we use a fully custom UI framework and why we wrote our own git library. But if you open a copy of Sublime Text 3 on a 4k display you may notice that it isn't quite keeping up. This is due to the CPU being used for rendering, which doesn't scale well to higher resolutions. Back in 2018 we decided to fix this performance problem using hardware accelerated rendering.

With Sublime Merge 2 and the upcoming Sublime Text 4 release we now have fully hardware accelerated rendering using OpenGL. This has enabled both applications to stay performant at resolutions as high as 8k. It has been enabled by default for macOS and can be optionally enabled on Linux and Windows under the "Advanced" section in the preferences dialog or using the "hardware_acceleration" setting. I hope to give a brief overview of how we achieved this and the choices we made along the way.

Choosing an API

Before we could start on an implementation we of course had to pick an API to use for controlling the GPU. We wanted a shared implementation for all the platforms we support, which immediately ruled out the Direct2D and Metal APIs. For flexibility and performance reasons we also didn't want to use a higher-level library like Skia, which we already make use of for CPU-based rendering. This left us with only two options: Vulkan and OpenGL.

Vulkan is the successor of OpenGL and comes with many performance advantages at the cost of some complexity. Its design simplifies the GPU drivers leading to more stable operating systems and applications. It would be our API of choice had Apple not decided against supporting it on their platforms. We did evaluate the viability of MoltenVK - a Vulkan implementation built on top of Apple's Metal API - however it doesn't support macOS 10.9 nor did it seem stable enough at the time. Unfortunately this didn't leave us any other choice than to use OpenGL.

OpenGL is 28 years old and currently the only truly cross-platform GPU API. It's supported by practically every GPU under the sun, but its complexity and multitude of implementations make the drivers more bug-prone and inconsistent. However since we only needed to render simple 2D geometry our hope was that the drivers wouldn't be much of an issue. Thankfully this also happened to be the API I was already familiar with, so getting reacquaint with its intricacies wasn't too difficult.

We also had to choose which version of OpenGL to target. We went with the latest version supported by Apple: OpenGL 4.1, as this version is relatively recent but also supported by most hardware.

Implementation

Owing to its history with DirectX, our UI framework was rather well positioned for adding hardware accelerated rendering. There was already a rendering abstraction layer in place called a "render context". Most widgets only used the basic primitives provided by the render context, though some also did rendering themselves. The plan was to start off basic on one platform (Linux), implementing the render context's functions one by one, then moving all the custom widget rendering into the render context and finally porting the rendering to the other platforms. The end goal being to reliably produce an almost identical rendering result (within rounding error).

The biggest problems we had were initially performance related. GPUs get their performance from doing work in parallel, unlike with a CPU where you can easily render small parts at a time you instead need to batch lots of small things together into a single render job. This is most apparent with text rendering where we see massive gains from batching glyphs together. This does mean that glyphs are mostly drawn out of order, which can easily result in odd rendering bugs if you're not careful. Overall the batching has some fairly complex logic behind it but most of it remained contained inside the render context. You can see below the improvement from just batching glyphs:

No Batching Batched x4 Batched x16 Batched x8192
Frame Time 52ms 17ms 8ms 3ms
Tests were done using AMD RX560 on Linux at 1440p; the time represents the full render time not just the glyphs.

Similarly many other rendering functions required slight alterations to work better with hardware accelerated rendering. Notably the gradients used for shadows, the squiggly underlines used for spell checking and text fading needed to be moved from custom render functions into the render context. Here's a demonstration of the full application being rendered:

After we had a fully working implementation for Linux we began the porting effort to macOS, which is where we encountered our first driver bug. Sadly this turned out to be a trend. To this date we've come across ~8 separate driver bugs on different platforms/hardware and have implemented various workarounds, feature blacklists or in one case an OS version blacklist. These bugs are the most frustrating part of working with OpenGL, but in the end adding these workarounds still seems simpler than having separate implementations using different APIs.

I'd like to mention RenderDoc as an invaluable tool for debugging on Linux and Windows.

End Result

The merge commit that introduced OpenGL came in at just under 9000 lines of code. After fixing a long initial wave of bugs it's been fairly stable since the release of Sublime Merge 2.

As you can see below, in its current state OpenGL rendering scales really well to higher resolutions. Even with a low-end dedicated GPU we're now faster at 4k/8k with hardware acceleration than at 1080p without, and are easily within the 16ms budget for a 60hz monitor.

Hardware 1366x768 1080p 1440p 4k 8k
Ubuntu 20.04 CPU (2990wx) 5ms 6ms 17ms
Ubuntu 20.04 AMD RX560 3ms 3ms 3ms
macOS 11.1 CPU (5250U) 5ms 12ms 30ms
macOS 11.1 Intel HD 6000 5ms 9ms 18ms
Windows 10 CPU (9900k) 7ms 21ms
Windows 10 2080ti 3ms 3ms

Future Considerations

The current implementation still leaves a fair amount of performance on the table, especially for non-dedicated GPUs. Although it's not strictly required it would be nice to do further optimizations for battery usage and older devices.

Apple deprecating OpenGL and improvements to MoltenVK make it clear that Vulkan support will at some point need to be added, though it's unclear how far away that is.

With upcoming Linux ARM support OpenGL is more important than ever due to the low-power CPUs in those kinds of devices. They also generally don't support recent versions of OpenGL, so the version requirement may need to be lowered in the future.

Sublime Merge Tips - Editing Git Commits

March 24, 2021 by Dylan Johnston

Here at Sublime HQ we use Sublime Merge every day to manage our Git repositories. As a result we've built lots of features to speed up our development.

In this post we'll share some of the ways we've made it easy to edit and adjust commits.

Continue reading on the full post.

Sublime Merge Build 2047

February 23, 2021 by Dylan Johnston

Today we're releasing the first Sublime Merge build of the year - Build 2047! This build brings plenty of new features and enhancements.

Continue reading the full post for more details.

Sublime Merge 2 - Features and Flexibility

May 26, 2020 by Dylan Johnston

From the first release of Sublime Merge, we talked about the simple joy of software that ‘gets it really right’. For our team it means going beyond the minimum, making software as good as it can be, and paying attention to the details.

It’s been almost two years since Sublime Merge was launched, and our focus hasn’t changed. Our aim for the newest update was to ‘get it really right’ when it comes to flexibility and customization.

Our community uses Sublime Merge in many different ways; from reviewing commits on a tablet, to writing thousands of lines of code on a desktop computer.

The latest version of Sublime Merge is packed full of upgrades, but we want to highlight some of the ways we’re giving you flexibility in the way you work. We’ve included the full list of changes at the bottom of this post (spoiler: there’s a lot)

  • Repository-Level Tabs - use tabs to quickly navigate between multiple repositories
  • Upgraded Commit UI - focus on what’s important with an upgraded commit UI
  • Flexible Layouts - adapt the layout to fit your context and workflow
  • Hardware Acceleration - harness your device's power with OpenGL rendering

To get started straight away, visit the download page.

Tabs. Tabs. Tabs.

As developers, we know that windows can be cumbersome. We want to give you the tools you need to focus on your work, not on managing windows.

The new update provides the flexibility to view all your projects in one window.

Repository Level Tabs

Upgraded Commit UI

We’ve re-worked the commit UI to support different workflows. You can now configure the commit message position, and toggle between individual files using file tabs. You’ll also notice the new file stats.

Upgraded Commit UI

Your Git Client. Your Layout.

With the wide variety of displays available today, it’s important to have a flexible layout that works for you. Starting today, you can simply select the layout that fits your set up. Whether you’re on your 4K desktop screen, your work laptop, or even a tablet, we’ve got you covered.

Flexible Layouts

Even Faster 🚀

We're excited to announce support for hardware acceleration in Sublime Merge. Powered by OpenGL, this will deliver significant rendering performance improvements on all platforms. It is enabled by default on MacOS, and can be controlled via the advanced section of the preferences.

What’s Next

Review Workflow

Many of us use Sublime Merge to manage and share our work, but some of us also use it to review work. File tabs have improved this process significantly, but there’s more work to do. Keep your eyes out for multiple improvements focused on improving your ability to review.

Image Diffs

If you’re using Git, chances are you’re working with images too. Just like code, it’s important to see what’s changed when modifying image files. We want to make reviewing image changes as seamless as reviewing code changes.

Plugin Support

It’s incredible to see what the community has built using the plugin system for Sublime Text. The plugin system offers the power and flexibility needed to truly personalize your experience. We know this is an important part of software that gets it really right, so we’ll be bringing it to Sublime Merge.

The Team Behind Sublime Merge

We’ve got big plans for the Sublime Merge team, and we’re full steam ahead! Our team is growing, and we’d like to welcome our new developer, David! You can thank him for features such as commit stats, the new console, and some great performance improvements in Sublime Merge.

Hello hello, I’m David, one of the software engineers at Sublime HQ. I’m usually the quiet guy that enjoys making silly jokes whenever I’m given the chance. As a programmer, I enjoy learning how to make traditional software, and writing clean compact code. In my own time I’ve been learning how to draw digitally.

Feedback

As always, we’re excited to hear your thoughts. We’ll be on the forum listening to any feedback. We also have an official bug tracker, where you can share your ideas for features.

Thank You

We know times are tough on a global scale at the moment, and our thoughts are with all of you. We’d like to take this time to thank you for your feedback and participation, whether it be on the forums or the Discord server. Through this, you have guided Sublime Merge to where it is today. We’re excited to continue delivering the best Git experience to you.

Sublime Merge 2 Changelog

General

  • New UI, including repository tabs
  • GPU Rendering
  • UI: Reworked Commit Dialog
  • UI: Added repository tabs, to have multiple repositories open in a single window
  • UI: Added file tabs when viewing the contents of a commit
  • Implement commit signature creation and validation
  • Added a lines changed indicator to commits
  • Added command history, available from the Show Git Output icon in the tool bar
  • Added commit message history, available from the dropdown arrow in the commit message box
  • Added support for non-overlay scrollbars in diffs
  • Added Resolve Ours / Resolve Theirs dropdown to unmerged files
  • URLs in commit messages and git output can be opened via the context menu
  • Left and Right keys can be used to expand/collapse merge commits
  • Added Navigate/Go to Child
  • Stash commands no longer supply -q by default, to work around a bug in Git 2.24
  • Checking out a hidden ref will make the ref visible
  • Add Recent Repositories to Welcome Page
  • Search: Added before and after operators
  • Added set_preference and toggle_preference commands
  • Added gitflow publish support
  • Preferences: Updating settings via the preferences dialog no longer clears comments in the settings file
  • Preferences: Added Preferences entry for Ignore Whitespace in diffs
  • Added checks for pushDefault and pushRemote when pushing
  • Added Tools/Show Console
  • Improved selection behavior while loading large repositories
  • Improved menu auto hide behavior on Linux and Windows
  • Improved performance with a very large number of untracked or modified files
  • Improved performance in repositories with a large number of authors
  • Running smerge without any arguments will focus the current window, if any
  • Fixed not being able to commit when email is set to empty string
  • Fixed a bug in destination path calculation in the clone dialog
  • Fixed Create Tag with an empty message creating the tag incorrectly
  • Fixed hunk staging using the wrong encoding in some scenarios
  • Fixed shift+enter staging a file even when focus is in commit message box

Merge Tool

  • Indentation settings are now automatically detected from the contents of the file
  • Saving a file with unresolved conflicts will warn before saving
  • Added a preference to trim trailing whitespace on save

GPU Rendering

  • New hardware_acceleration setting will composite the UI on the GPU
  • By default, GPU rendering is enabled on Mac, and disabled on Windows and Linux. This can be changed via the Preferences dialog.
  • Details about the active GPU will be displayed in the Console

Git

  • Git: Added support for smudge and clean filters, enabling Git LFS support
  • Git: Improved handling of the working-tree-encoding attribute
  • Git: Improved parsing of .gitattributes files
  • Git: Added support for GUI encoding config
  • Windows and Mac: Updated bundled Git to 2.26.2
  • Windows: Fixed core.worktree support
  • Submodules: Added Initialize All Submodules context menu
  • Submodules: The location bar now indicates the value of HEAD for each submodule

Editor Control

  • Expanded draw_white_space setting, supporting leading and trailing white space
  • Unicode white space characters, such as the zero width no-break space, are now drawn as hex values. Controlled via draw_unicode_white_space setting.
  • Spell Checking: Added support for languages with upper case characters after start of word
  • Spell Checking: Updated dictionaries
  • Spell Checking: Added support for non-utf8 dictionaries
  • Spell Checking: System dictionaries are now available on Linux
  • Spell Checking: Dictionaries in ~/Library/Spelling are now available on Mac
  • Linux: Text drag and drop is now supported
  • Linux: Added support for alternate font weight names
  • Linux: Selection is no longer cleared when another application makes a selection

Text Commands

  • Improved behavior of Wrap Paragraph
  • Improved behavior of Swap Lines
  • Added Selection/Expand Selection as a general mechanism to expand the selection
  • Selection/Split into Lines will now split a selection into words if the selection doesn't contain any newlines
  • Fixed swap_line_down not being able to swap an empty line onto the last line of a file

Input Handling

  • Modifier key taps can now be used as part of a key binding. For example, ["ctrl", "ctrl"] will trigger when Ctrl is pressed twice without pressing any other keys in between.
  • Linux: AltGr can now be used in key bindings via altgr
  • Linux: Added a workaround for a touchscreen driver bug, which would cause right click and mouse scrolling to stop working
  • Linux: When the menu is hidden, pressing alt will show it
  • Linux: Improved compatibility with some keyboard layouts
  • Mac: Fix Pinyin input
  • Mac: Keypad keys can now be bound to as expected
  • Mac: Improved compatibility with some keyboard layouts
  • Windows, Linux: Hide mouse cursor when typing. Controlled via hide_pointer_while_typing setting.
  • Windows, Linux: Fixed being unable to bind Ctrl+Break
  • Windows: Improved IME support
  • Windows, Linux: Added Shift+F10 key binding to open the context menu

UI

  • Added highlight_gutter and highlight_line_number settings
  • Themes now have a style property for title_bar element, for better integration with OS "dark modes"
  • Color Schemes: Added glow font option to color schemes
  • Color Schemes: Added support for the underline font style
  • Linux: Show sequential key bindings in the menu
  • Linux: Fixed context menu position being slightly offset

Rendering

  • Windows, Linux: Added support for per-display subpixel ordering
  • Mac: Improved window resize performance
  • Windows: Fixed rendering bug where other applications could cause persistent artifacts via window animations

Application Behavior

  • Added Safe Mode, to simulate a clean install. Enabled by passing --safe-mode on the command line.
  • Holding down Shift on Windows, or Option on macOS, will start Sublime Merge in Safe Mode
  • Settings containing a UTF-8 BOM will no longer fail to load

Syntax Definitions

  • Added ability to "branch" within syntax definitions, for non-deterministic or multi-line constructs
  • Many syntax highlighting improvements, including significant improvements to:
  • Improved syntax definition load time
  • Fixed a performance issue with bounded repeats in regular expressions

Use mmap With Care

May 2, 2019 by Benjamin Schaaf

When we implemented the git portion of Sublime Merge, we chose to use mmap for reading git object files. This turned out to be considerably more difficult than we had first thought. Using mmap in desktop applications has some serious caveats, and here's why:

You can follow along with the example project here.

Say you were reading some binary format, data you need throughout some application. You take the easiest approach and use a simple read to get the full contents of the file. You release your software and someone comes along and says: "I need to parse this 3GB file, but I only have 2GB of memory. Could you make it so that you're not using so much memory?". Of course you want to help them, so you do some searching and come to the conclusion that memory mapping is the perfect solution to this problem.

Memory mapped files work by mapping the full file into a virtual address space and then using page faults to determine which chunks to load into physical memory. In essence it allows you to access the file as if you had read the whole thing into memory, without actually doing so. Crucially it requires only a small change to the codebase:

And with that, you've fixed the memory usage issue. You've fixed the bug, people are happy and all is well until you get another support ticket. Your program is crashing with a SIGBUS.

Caveat 1: SIGBUS

SIGBUS (bus error) is a signal that happens when you try to access memory that has not been physically mapped. This is different to a SIGSEGV (segmentation fault) in that a segfault happens when an address is invalid, while a bus error means the address is valid but we failed to read/write.

As it turns out, the ticket comes from someone using a networked drive. Their network happened to disconnect while your memory mapped file was open, and since the file no longer existed the OS couldn't load it into ram for you and gave you a SIGBUS instead.

Because the OS is loading the file on demand, you now have this wonderful issue where any arbitrary read from an address into the memory mapped file can and will fail at some point.

Luckily on POSIX systems we have signal handlers, and SIGBUS is a signal we can handle. All you need to do is register a signal handler for SIGBUS when the program starts and jump back to our code to handle failures there.

Sadly our code actually has some edge cases we should consider:

Signal handlers are global, but signals themselves are per-thread. So you need to make sure you're not messing with any other threads by making all our data thread local. Let's also add some robustness by making sure we've called setjmp before longjmp.

Using setjmp and longjmping from a signal handler is actually unsafe. It seems to cause undefined behaviour, especially on MacOS. Instead we must use sigsetjmp and siglongjmp. Since we're jumping out of a signal handler, we need that signal handler to not block any future signals, so we must also pass SA_NODEFER to sigaction.

This is starting to get quite complicated, especially if you were to have multiple places where a SIGBUS could happen. Let's factor things out into functions to make the logic a little cleaner.

There, now you just need to remember to always call install_signal_handlers for every application, and wrap all file accesses with safe_mmap_try. Annoying, but manageable. So now you've covered POSIX systems, but what about Windows?

Caveat 2: Windows

Windows doesn't have mmap, but it does have MapViewOfFile. Both of these implement memory mapped files, but there's one important difference: Windows keeps a lock on the file, not allowing it to be deleted. Even with the Windows flag FILE_SHARE_DELETE deletion does not work. This is an issue when we expect another application to delete files from under us, such as git garbage collection.

One way around this with the windows API is to essentially disable the system file cache entirely, which just makes everything absurdly slow. The way Sublime Merge handles this is by releasing the memory mapped file on idle. Its not a pretty solution, but it works.

Windows also does not have a SIGBUS signal, but you can trivially use structured exception handling in safe_mmap_try instead:

Now all is well, your application functions on Windows. But then you decide that you would like some crash reporting, to make it easier to identify issues in the future. So you add Google Breakpad, but unbeknownst to you you've just broken Linux and MacOS again…

Caveat 3: 3rd Parties

The problem with using signal handlers is that they're global, across threads and libraries. If you have or have added a library like Breakpad that uses signals internally you're going to break your previously safe memory mapping.

Breakpad registers signal handlers at initialization time on Linux, including one for SIGBUS. These signal handlers override each other, so installation order is important. There is not a nice solution to these types of situations: You can't simply set and reset the signal handler in safe_mmap_try as that would break multithreaded applications. At Sublime HQ our solution was to turn an unhandled SIGBUS in our signal handler into a SIGSEGV. Not particularly elegant but it's a reasonable compromise.

On MacOS things get a little more complicated. XNU, the MacOS kernel, is based on Mach, one of the earliest microkernels. Instead of signals, Mach has an asynchronous, message based exception handling mechanism. For compatibility reasons signals are also supported, with Mach exceptions taking priority. If a library such as Breakpad registers for Mach exception messages, and handles those, it will prevent signals from being fired. This is of course at odds with our signal handling. The only workaround we've found so far involves patching Breakpad to not handle SIGBUS.

3rd party libraries are a problem because signals are global state accessible from everywhere. The only available solutions to this are unsatisfying workarounds.

Caveat 4: 32bit Support

Memory mapping may not use physical memory, but it does require virtual address space. On 32bit platforms your address space is ~4GB. So while your application may not use 4GB of memory, it will run out of address space if you try to memory map a too large file. This has the same result as being out of memory.

Sadly this doesn't have a workaround like the other issues, it is a hard limitation of how memory mapping works. You can now either rewrite the codebase to not memory map the whole file, live with crashes on 32bit systems or not support 32bit.

With Sublime Merge and Sublime Text 3.2 we took the "no 32bit support" route. Sublime Merge does not have a 32bit build available and Sublime Text disables git integration on 32bit versions.

An Alternative

I mentioned before that you can rewrite your code to not use memory mapping. Instead of passing around a long lived pointer into a memory mapped file all around the codebase, you can use functions such as pread to copy only the portions of the file that you require into memory. This is less elegant initially than using mmap, but it avoids all the problems you're otherwise going to have.

Through some quick benchmarks for the way Sublime Merge reads git object files, pread was around ⅔ as fast as mmap on linux. In hindsight it's difficult to justify using mmap over pread, but now the beast has been tamed and there's little reason to change any more.

If you think we've missed something or made a mistake, please leave us a message on the forums. We hope this helps some of you in your future endeavours. If you haven't already, check out our git client Sublime Merge.

Sublime Text 3.2

March 13, 2019 by Will Bond

The past year has been busy here at Sublime HQ. We've grown our engineering team, shipped Sublime Text 3.1 and released our second product, Sublime Merge. If you use Git and like the ethos of Sublime Text, we think you'll love it.

Today we're pushing out Sublime Text 3.2, which builds off of a bunch of work we've done in Sublime Merge. This includes: first-class Git integration, incremental diffing, new theme functionality and block caret support. Beyond that is a slew of other enhancements, stability improvements and performance gains. See the full changelog below for details.

Sublime Text 3.2 is available from the Download page.

Git status badges in the side bar and incremental diff markers in the gutter

Changelog

Git Integration New!

  • Files and folders in the sidebar will now display badges to indicate Git status
  • Ignored files and folders are visually de-emphasized
  • The current Git branch and number of modifications is displayed in the status bar
  • Commands have been added to open a repository, see file or folder history, or blame a file in Sublime Merge
  • Themes may customize the display of sidebar badges and status bar information
  • The setting show_git_status allows disabling Git integration
  • All file reads are done through a custom, high-performance Git library written for Sublime Merge
  • Read the documentation

Incremental Diff New!

  • All changes to a document are now represented by dedicated markers in the gutter
  • Diff markers show added, modified and deleted lines
  • The setting mini_diff controls incremental diff behavior
  • In coordination with the new Git functionality, diffs can be calculated against HEAD or the index
  • The git_diff_target setting controls base document source
  • API methods View.set_reference_document() and View.reset_reference_document() allow controlling the diff
  • The following diff-related commands were added:
    • Next Modification
    • Previous Modification
    • Revert Modification
  • Full inline diffs of each change can be displayed via the right-click context menu, or keyboard shortcuts
  • Inline diff presentation can be changed by customizing a color scheme
  • Read the documentation

Editor Control

  • Added block_caret setting
  • Improve positioning and sizing of gutter icons in some situations
  • Fixed draw_minimap_border setting not working
  • Linux: Improved input method (IM) support - fcitx, ibus, etc
  • Linux: Fixed a crash when using GTK_IM_MODULE=xim
  • Linux: Tweaked behavior of up/down when on the first and last lines of a file to better match platform conventions
  • Windows: Improved IME support

Themes/UI

  • Enhanced the .sublime-theme format:
    • Added variables support and associated revised JSON format with variables key
    • Added extends keyword to have one theme derive from another
    • Colors may be specified via CSS syntax
  • Improved performance with large numbers of rules in a .sublime-theme
  • Linux: Moved to GTK3
  • Linux: Various high DPI fixes
  • Mac: Added Mojave support
  • Mac: Add full support for macOS native tabs
  • Mac: Ensure context menus are shown without scrolling
  • Mac: Error message dialogs can now be closed with the escape key
  • Mac: Improved window placement
  • Mac: Improved resize performance
  • Windows: Fixed minimized and maximized state not restoring
  • Windows: Fixed a bug where auto complete entries would contain an ellipsis when not required

Text Rendering

  • Support for Unicode 11.0
  • Improved rendering of combining characters
  • Fixed a caret positioning bug when non-trivial graphemes are present
  • Fixed some cases of incorrect glyph positions on Windows and Mac
  • Linux: Color glyphs are now drawn properly on light backgrounds
  • Windows: Fixed a rendering issue with certain combining characters
  • Windows: Fixed some fonts having an incorrect baseline

Color Schemes

  • Added block_caret key to use in conjunction with block carets
  • caret values now respect alpha as expected, rather than pre-blending against the background color
  • Added the foreground_adjust property to rules with a background. Accepts CSS color mod adjusters to manipulate the saturation, lightness or opacity of the foreground color.

Syntax Highlighting

  • Many syntax highlighting improvements, including significant improvements to:
  • Fixed a crash that could occur when nesting embed patterns in .sublime-syntax files
  • Syntax Tests: Allow syntax test files to have a UTF-8 BOM

Files and Folders

  • Improve performance of file watching for ignored paths on Windows and Mac
  • Windows: Fixed Open File treating paths as case-sensitive
  • Windows: Properly unlock directories after contained files are closed

API

  • Added View.set_reference_document() and View.reset_reference_document() to control diff generation
  • Phantoms are now drawn correctly in conjunction with draw_centered
  • Various minor improvements related to plugin module loading and unloading
  • Added support for hwb() colors to minihtml
  • Added a custom min-contrast() adjuster for the CSS color mod function in minihtml
  • Mac: Fixed a plugin_host crash when running a process that itself crashes

Miscellaneous

  • Fixed a Goto Symbol in Project performance regression
  • F21..F24 keys can now be bound
  • Assorted minor fixes and stability improvements
  • Linux: Improved behavior of --wait command line argument when Sublime Text isn't currently running

Sublime Merge Build 1107

March 12, 2019 by Jon Skinner

Sublime Merge, our Git Client and Merge Tool, is out now with improvements to the Merge Tool, Tree viewing, and Clone dialog. See the full post for more details.

Sublime Text 3.2 will be coming very soon now, featuring Git integration and more.