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