xref: /openbsd-src/gnu/llvm/clang/tools/clang-format/clang-format-sublime.py (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
1*e5dd7070Spatrick# This file is a minimal clang-format sublime-integration. To install:
2*e5dd7070Spatrick# - Change 'binary' if clang-format is not on the path (see below).
3*e5dd7070Spatrick# - Put this file into your sublime Packages directory, e.g. on Linux:
4*e5dd7070Spatrick#     ~/.config/sublime-text-2/Packages/User/clang-format-sublime.py
5*e5dd7070Spatrick# - Add a key binding:
6*e5dd7070Spatrick#     { "keys": ["ctrl+shift+c"], "command": "clang_format" },
7*e5dd7070Spatrick#
8*e5dd7070Spatrick# With this integration you can press the bound key and clang-format will
9*e5dd7070Spatrick# format the current lines and selections for all cursor positions. The lines
10*e5dd7070Spatrick# or regions are extended to the next bigger syntactic entities.
11*e5dd7070Spatrick#
12*e5dd7070Spatrick# It operates on the current, potentially unsaved buffer and does not create
13*e5dd7070Spatrick# or save any files. To revert a formatting, just undo.
14*e5dd7070Spatrick
15*e5dd7070Spatrickfrom __future__ import absolute_import, division, print_function
16*e5dd7070Spatrickimport sublime
17*e5dd7070Spatrickimport sublime_plugin
18*e5dd7070Spatrickimport subprocess
19*e5dd7070Spatrick
20*e5dd7070Spatrick# Change this to the full path if clang-format is not on the path.
21*e5dd7070Spatrickbinary = 'clang-format'
22*e5dd7070Spatrick
23*e5dd7070Spatrick# Change this to format according to other formatting styles. See the output of
24*e5dd7070Spatrick# 'clang-format --help' for a list of supported styles. The default looks for
25*e5dd7070Spatrick# a '.clang-format' or '_clang-format' file to indicate the style that should be
26*e5dd7070Spatrick# used.
27*e5dd7070Spatrickstyle = None
28*e5dd7070Spatrick
29*e5dd7070Spatrickclass ClangFormatCommand(sublime_plugin.TextCommand):
30*e5dd7070Spatrick  def run(self, edit):
31*e5dd7070Spatrick    encoding = self.view.encoding()
32*e5dd7070Spatrick    if encoding == 'Undefined':
33*e5dd7070Spatrick      encoding = 'utf-8'
34*e5dd7070Spatrick    regions = []
35*e5dd7070Spatrick    command = [binary]
36*e5dd7070Spatrick    if style:
37*e5dd7070Spatrick      command.extend(['-style', style])
38*e5dd7070Spatrick    for region in self.view.sel():
39*e5dd7070Spatrick      regions.append(region)
40*e5dd7070Spatrick      region_offset = min(region.a, region.b)
41*e5dd7070Spatrick      region_length = abs(region.b - region.a)
42*e5dd7070Spatrick      command.extend(['-offset', str(region_offset),
43*e5dd7070Spatrick                      '-length', str(region_length),
44*e5dd7070Spatrick                      '-assume-filename', str(self.view.file_name())])
45*e5dd7070Spatrick    old_viewport_position = self.view.viewport_position()
46*e5dd7070Spatrick    buf = self.view.substr(sublime.Region(0, self.view.size()))
47*e5dd7070Spatrick    p = subprocess.Popen(command, stdout=subprocess.PIPE,
48*e5dd7070Spatrick                         stderr=subprocess.PIPE, stdin=subprocess.PIPE)
49*e5dd7070Spatrick    output, error = p.communicate(buf.encode(encoding))
50*e5dd7070Spatrick    if error:
51*e5dd7070Spatrick      print(error)
52*e5dd7070Spatrick    self.view.replace(
53*e5dd7070Spatrick        edit, sublime.Region(0, self.view.size()),
54*e5dd7070Spatrick        output.decode(encoding))
55*e5dd7070Spatrick    self.view.sel().clear()
56*e5dd7070Spatrick    for region in regions:
57*e5dd7070Spatrick      self.view.sel().add(region)
58*e5dd7070Spatrick    # FIXME: Without the 10ms delay, the viewport sometimes jumps.
59*e5dd7070Spatrick    sublime.set_timeout(lambda: self.view.set_viewport_position(
60*e5dd7070Spatrick      old_viewport_position, False), 10)
61