, последнее обновление:

Sublime Text 4 как Golang IDE

Необходимо установить менеджер пакетов https://packagecontrol.io, установка доступна через Command Pallette (CTRL+SHIFT+P или CMD+SHIFT+P на macOS).

Соглашения гайда

Данные элементы являются “соглашением по-умолчанию”, если не обговорено иное:

  • Все пакеты устанавливаются с помощью Package Control: жмем CTRL+SHIFT+P (CMD+SHIFT+P на macOS), ищем Package control: Install Package (работает автокомплит), жмем Enter. Спустя несколько секунд откроется меню со списком доступных для установки плагинов. Начните вводить название плагина из заголовка для сортировки списка. Установка осуществляется нажатием на Enter.
  • Практически у всех пакетов есть клавиатурные сокращения, если они не являются плагином к плагину. Для просмотра оных перейдите в Preferences → Package Settings → ИМЯ ПЛАГИНА → Key Bindings.
  • У всего и вся есть дефолтные конфиги, которые показываются в левой части окна. Даже для плагинов и плагинов плагинов.

Перед всеми делами

Sublime Text подгружает переменные окружения через параметр –login (или -l) шелла. Поведение шеллов может отличаться из-за этой переменной, поэтому при необходимости сделайте:

  • Симлинк ~/.zshrc~/.zprofile для ZSH.
  • Установите параметр shell_environment (см. далее).

Конфигурация самого Sublime Text

Я предпочитаю следующую конфигурацию:

// Settings in here override those in "Default/Preferences.sublime-settings",
// and are overridden in turn by syntax-specific settings.
{
    "always_prompt_for_file_reload": false,
    "always_show_minimap_viewport": true,
    "animation_enabled": false,
    "auto_complete_commit_on_tab": true,
    "auto_complete_cycle": true,
    "auto_complete_with_fields": true,
    "block_caret": false,
    "bold_folder_labels": true,
    "caret_style": "phase",
    "caret_extra_bottom": 0,
    "caret_extra_top": 0,
    "draw_minimap_border": true,
    "draw_white_space": ["trailing", "isolated"],
    "ensure_newline_at_eof_on_save": true,
    "font_face": "JetBrains Mono",
    "font_options":
    [
    ],
    "font_size": 14,
    "highlight_line": true,
    "ignored_packages":
    [
        "Vintage",
    ],
    "line_padding_bottom": -1,
    "line_padding_top": -1,
    "match_brackets_angle": true,
    "native_tabs": "preferred",
    "shift_tab_unindent": true,
    "show_encoding": true,
    "theme": "Spacegray.sublime-theme",
    "trim_trailing_white_space_on_save": true,
    "word_wrap": true,
    "color_scheme": "Packages/One Half Color Schemes/OneHalfDark.tmTheme",
    "dark_theme": "Default Dark.sublime-theme",
    "light_theme": "Default.sublime-theme",
    "rulers": [120],
    "dictionary": "Packages/Language - English/en_US.dic",
    "spacegray_sidebar_font_xlarge": true,
    "spacegray_fileicons": true,
    "hardware_acceleration": "opengl",
	"shell_environment": "/bin/zsh",
}
  • always_prompt_for_file_reload должен быть в false, чтобы тот же gofumports не заставлял перезагружать файлы, которые открыты в редакторе и были им исправлены.
  • По-умолчанию каретка вылезает за пределы строки на несколько пикселей, поэтому добавлены параметры caret_extra_*.
  • Для контроля межстрочного интервала (высоты строки) используются параметры line_padding_*.
  • lsp_format_on_save переехал-таки в конфиг LSP!
  • Для включения объединения всех окон Sublime Text в одно используется параметр native_tabs, ибо у меня часто открыто более одного проекта и так удобнее переключаться между ними.
  • Переменные spacegray_* от темы Spacegray, можете их удалить при необходимости.
  • shell_environment необходимо установить в текущий выбранный шелл, особенно если это не Bash.

Обязательное

LSP

Этот плагин реализует Language Server Protocol и позволяет использовать gopls, который уже давно и прочно поселился в VSCode и стал, практически, стандартным средством линтинга исходников на Go.

Перейдите в Preferences → Package settings → LSP → Settings и скопируйте туда глобальный конфиг:

{
	"lsp_format_on_save": true,
	"show_diagnostics_count_in_view_status": true,
    "show_diagnostics_in_view_status": true,
    "show_code_actions_bulb": true,
    "show_symbol_action_links": true,
    "show_references_in_quick_panel": true,
}

Конфигурация клавиатурных сокращений настраивается в Preferences → Package settings → LSP → Key Bindings:

[
    {"keys": ["command+shift+f12"], "command": "lsp_symbol_implementation", "context": [{"key": "setting.lsp_active"}]},
    {"keys": ["command+alt+shift+f12"], "command": "lsp_symbol_type_definition", "context": [{"key": "setting.lsp_active"}]},
    {"keys": ["f12"], "command": "lsp_symbol_definition", "context": [{"key": "setting.lsp_active"}]},
    {"keys": ["primary+shift+m"], "command": "lsp_show_diagnostics_panel", "context": [{"key": "setting.lsp_active"}]},
    {"keys": ["primary+shift+c"], "command": "lsp_code_actions", "context": [{"key": "setting.lsp_active"}]},
]

В этом примере используются следующие сокращения:

  • CMD+SHIFT+F12 - перейти к имплементации (или показать список доступных имплементаций).
  • CMD+ALT+SHIFT+F12 - перейти к определению типа.
  • F12 - перейти к определению символа (перезаписывает поведение Sublime Text на более контекстное).
  • CMD+SHIFT+M - показать панель с выводом от LSP (если есть ошибки, например).
  • CMD+SHIFT+C - показать действия с кодом (Code Actions).

LSP-gopls

Этот плагин необходимо поставить через Package Control. Он позволяет подцепить к LSP сам gopls.

Для работы этого плагина необходим установленный gopls где-то в PATH. В противном случае можно будет дописать полный путь до него в конфигурации (см. ниже).

Что нужно знать:

  1. В случае отсутствия gopls в PATH плагин подтянет его автоматически при первом открытии исходников на Go.
  2. Запуск gopls осуществляется автоматически при открытии файлов с расширением go.
  3. Установка и обновление gopls будут также выполнены автоматически.

В общем, делать не надо вообще ничего, все просто работает. Но я бы немного “доконфигурил” gopls в Preferences → Package settings → LSP → Servers → LSP-gopls:

{
	"settings": {
		"gopls.experimentalWorkspaceModule": true,
		"gopls.gofumpt": true,
		"gopls.usePlaceholders": true
	}
}

SublimeLinter

Этот плагин на самом деле является неким “метаплагином”, ибо у него есть свои плагины, которые реализуют интерфейс общения с линтерами.

Нам необходимо поставить как минимум SublimeLinter-golangcilint, для использования металинтера golangci-lint.

Доконфигуриваем в Preferences → Package settings → SublimeLinter → Settings::

{
	"lint_mode": "load_save",
    "no_column_highlights_line": true
    "linters": {
    	"golangcilint": {
    		"working_dir": "${folder}"
    	}
    }
}

Этот конфиг заставляет golangci-lint работать на весь проект, а не только на текущий файл (и все, что им используется).

Gomod

Это подсветка синтаксиса для файлов go.mod и go.sum.

ApplySyntax

Этот плагин позволяет применять какой-то синтаксис к каким-то открытым файлам. Например, можно всем YAML файлам, лежащим по определенным путям, принудительно выставлять синтаксиси Ansible (который появляется вместе с установленным одноименным плагином).

В примере ниже конфигурация для двух штук - Ansible и gohtml шаблонов, для шаблонизатора Golang:

{
    // If you want exceptions reraised so you can see them in the console, change this to true.
    "reraise_exceptions": true,

    // If you want to have a syntax applied when new files are created, set new_file_syntax to the name of the syntax
    // to use.  The format is exactly the same as "syntax" in the rules below. For example, if you want to have a new
    // file use JavaScript syntax, set new_file_syntax to 'JavaScript'.
    "new_file_syntax": true,

    // Auto add extensions to language settings file in User folder.
    // Do not manually remove "apply_syntax_extensions" from the settings file.
    // "extenstions" are ignored by "match": "all" setting.
    "add_exts_to_lang_settings": true,

    // Control level of logging in the console.
    // (true|false|"verbose")
    "debug": "verbose",

    // Put your custom syntax rules here:
    "syntaxes": [
        {
            "syntax": "Ansible/Ansible",
            "rules": [
                {"file_path": ".*/tasks/.*.yml$"},
                {"file_path": ".*/handlers/.*.yml$"},
                {"file_path": ".*/*_vars/.*.yml$"},
                {"file_path": ".*/roles/.*.yml$"},
                {"file_path": ".*/playbooks/.*.yml$"},
                {"file_path": ".*/.*ansible.*/.*.yml$"}
            ]
        },
        {
            "syntax": "User/GoHTML",
            "rules": [
                {"file_path": ".*/.*.gohtml$"},
            ]
        }
    ]
}

GoHTML и GoTemplate

По-умолчанию, конечно же, Sublime Text не поддерживает никакую работу с шаблонами для стандартных html/template и text/template, но был когда-то такой популярный плагин GoSublime (и, в принципе, существующий сейчас и даже рабочий), который добавлял поддержку оных. Но нам придется делать это вручную, к сожалению.

Нам нужно положить 2 файла в $SUBLIME_HOME/Packages/User. В файл GoHTML.sublime-syntax кладем следующее:

%YAML 1.2
---
name: 'GoHTML'
file_extensions:
  - gohtml
  - html.go
scope: text.html.gohtml
contexts:
  main:
      - match: ''
        push: 'Packages/HTML/HTML.sublime-syntax'
        with_prototype:
          - match: '{{'
            captures:
              0: punctuation.section.embedded.begin.gotemplate
            push: Packages/User/GoTemplate.sublime-syntax
            with_prototype:
              - match: '}}'
                captures:
                  0: punctuation.section.embedded.end.gotemplate
                pop: true

А в файл GoTemplate.sublime-syntax кладем следующее:

%YAML 1.2
---
name: 'GoTemplate'
scope: source.gotemplate
hidden: true
contexts:
  main:
    - match: ":="
      scope: keyword.operator.initialize.gotemplate
    - match: \|
      scope: keyword.operator.pipe.gotemplate
    - match: '[.$][\w]*'
      scope: variable.other.gotemplate
    - match: \b(if|else|range|template|with|end|nil|define)\b
      scope: keyword.control.gotemplate
    - match: \b(and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b
      scope: support.function.builtin.gotemplate
    - match: /\*
      push:
        - meta_scope: comment.block.gotemplate
        - match: \*/
          pop: true
    - match: '"'
      captures:
        0: punctuation.definition.string.begin.gotemplate
      push:
        - meta_scope: string.quoted.double.gotemplate
        - match: '"'
          captures:
            0: punctuation.definition.string.end.gotemplate
          pop: true
        - include: string_placeholder
        - include: string_escaped_char
    - match: "`"
      captures:
        0: punctuation.definition.string.begin.gotemplate
      push:
        - meta_scope: string.quoted.raw.gotemplate
        - match: "`"
          captures:
            0: punctuation.definition.string.end.gotemplate
          pop: true
        - include: string_placeholder
  string_escaped_char:
    - match: '\\(\\|[abfnrtv''"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3})'
      scope: constant.character.escape.gotemplate
    - match: \\.
      scope: invalid.illegal.unknown-escape.gotemplate
  string_placeholder:
    - match: |-
        (?x)%
            (\d+\$)?                                    # field (argument #)
            [#0\- +']*                                  # flags
            [,;:_]?                                     # separator character (AltiVec)
            ((-?\d+)|\*(-?\d+\$)?)?                     # minimum field width
            (\.((-?\d+)|\*(-?\d+\$)?)?)?                # precision
            [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%]     # conversion type        
      scope: constant.other.placeholder.gotemplate
    - match: "%"
      scope: invalid.illegal.placeholder.gotemplate

С помощью плагина ApplySyntax можно эти синтаксисы назначать на нужные файлы. В примере выше уже есть назначение GoHTML всем файлам, которые оканчиваются на .gohtml.

Дополнительные полезности

Дополнительно можно поставить еще следующие плагины:

Плагин Описание
Ansible Подсветка синтаксиса для Ansible. Внимание: выставлять файлам тип для подсветки, возможно, придется вручную!
Bracket Highlighter Подсветка скобок текущего участка кода.
Dockerfile Syntax Highlighting Подсветка синтаксиса для Dockerfile.
GitGutter Крайне удобное дополнение, показывающее текущее состояние измененности кода в столбце с номерами строк. Также можно включить инлайн-отображение последнего человека, который изменил строку.
Jinja2 Плагин для работы с шаблонами Jinja2, которые используются, например, в Ansible.
MarkdownLivePreview Лайв превью (в отдельном окне) редактируемого Markdown файла.
SideBar Enchancements Много годных дополнений для сайдбара - возможность нормально создавать, удалять, переименовывать, переимещать файлы и директории, открывать в браузерах и многое другое.

Дополнительные плагины LSP, которые я бы порекомендовал поставить:

Плагин Описание
LSP-dockerfile LSP для Dockerfile, если вы часто с ними работаете - крайне удобная штука.
LSP-json LSP для JSON файлов, включая файлы конфигурации.
LSP-yaml LSP для YAML файлов, может валидировать последние по JSON Schema (например, из JSON schema store).

Дополнительные линтеры, которые я бы порекомендовал поставить

Линтер Описание
SublimeLinter-contrib-ansible-lint Must have если вы работаете с Ansible.
SublimeLinter-contrib-makrdownlint Линтер для Markdown файлов (с помощью markdownlint).
SumlimeLinter-contrib-yamllint Линтер для YAML файлов.
SublimeLinter-shellcheck Линтер для шелловых скриптов, использует shellcheck.