16d528ed9Sopenharmony_ci# Copyright 2014 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci# found in the LICENSE file. 46d528ed9Sopenharmony_ci# 56d528ed9Sopenharmony_ci# Based on clang-format.py. 66d528ed9Sopenharmony_ci# 76d528ed9Sopenharmony_ci# This file is a minimal gn format vim-integration. To install: 86d528ed9Sopenharmony_ci# - Change 'binary' if gn is not on the path (see below). 96d528ed9Sopenharmony_ci# - Add to your .vimrc: 106d528ed9Sopenharmony_ci# 116d528ed9Sopenharmony_ci# map <F1> :pyxf <path-to-this-file>/gn-format.py<CR> 126d528ed9Sopenharmony_ci# 136d528ed9Sopenharmony_ci# gn format currently formats only a complete file so visual ranges, etc. won't 146d528ed9Sopenharmony_ci# be used. It operates on the current, potentially unsaved buffer and does not 156d528ed9Sopenharmony_ci# create or save any files. To revert a formatting, just undo. 166d528ed9Sopenharmony_ci 176d528ed9Sopenharmony_cifrom __future__ import print_function 186d528ed9Sopenharmony_ciimport difflib 196d528ed9Sopenharmony_ciimport subprocess 206d528ed9Sopenharmony_ciimport sys 216d528ed9Sopenharmony_ciimport vim 226d528ed9Sopenharmony_ci 236d528ed9Sopenharmony_ci# Change this to the full path if gn is not on the path. 246d528ed9Sopenharmony_cibinary = 'gn' 256d528ed9Sopenharmony_ciif vim.eval('exists("g:gn_path")') == "1": 266d528ed9Sopenharmony_ci binary = vim.eval('g:gn_path') 276d528ed9Sopenharmony_ci 286d528ed9Sopenharmony_cidef main(): 296d528ed9Sopenharmony_ci # Get the current text. 306d528ed9Sopenharmony_ci buf = vim.current.buffer 316d528ed9Sopenharmony_ci text = '\n'.join(buf) 326d528ed9Sopenharmony_ci 336d528ed9Sopenharmony_ci is_win = sys.platform.startswith('win32') 346d528ed9Sopenharmony_ci # Avoid flashing an ugly cmd prompt on Windows when invoking gn. 356d528ed9Sopenharmony_ci startupinfo = None 366d528ed9Sopenharmony_ci if is_win: 376d528ed9Sopenharmony_ci startupinfo = subprocess.STARTUPINFO() 386d528ed9Sopenharmony_ci startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW 396d528ed9Sopenharmony_ci startupinfo.wShowWindow = subprocess.SW_HIDE 406d528ed9Sopenharmony_ci 416d528ed9Sopenharmony_ci # Call formatter. Needs shell=True on Windows due to gn.bat in depot_tools. 426d528ed9Sopenharmony_ci p = subprocess.Popen([binary, 'format', '--stdin'], 436d528ed9Sopenharmony_ci stdout=subprocess.PIPE, stderr=subprocess.PIPE, 446d528ed9Sopenharmony_ci stdin=subprocess.PIPE, startupinfo=startupinfo, 456d528ed9Sopenharmony_ci shell=is_win, universal_newlines=True) 466d528ed9Sopenharmony_ci stdout, stderr = p.communicate(input=text) 476d528ed9Sopenharmony_ci if p.returncode != 0: 486d528ed9Sopenharmony_ci print('Formatting failed, please report to gn-dev@chromium.org.') 496d528ed9Sopenharmony_ci print(stdout, stderr) 506d528ed9Sopenharmony_ci else: 516d528ed9Sopenharmony_ci # Otherwise, replace current buffer. 526d528ed9Sopenharmony_ci lines = stdout.split('\n') 536d528ed9Sopenharmony_ci # Last line should have trailing \n, but we don't want to insert a blank 546d528ed9Sopenharmony_ci # line at the end of the buffer, so remove that. 556d528ed9Sopenharmony_ci if lines[-1] == '': 566d528ed9Sopenharmony_ci lines = lines[:-1] 576d528ed9Sopenharmony_ci sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines) 586d528ed9Sopenharmony_ci for op in reversed(sequence.get_opcodes()): 596d528ed9Sopenharmony_ci if op[0] != 'equal': 606d528ed9Sopenharmony_ci vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]] 616d528ed9Sopenharmony_ci 626d528ed9Sopenharmony_cimain() 63