def formatBde(): buf = vim.current.buffer lineSource = lambda row: buf[row] try: row, col = vim.current.window.cursor startEnd, lines = bdeformatutil.formatBde(lineSource, row - 1, col) except ValueError as e: print e return # Figure out if we need to add or remove lines startRow, endRow = startEnd oldLines = endRow - startRow + 1 newLines = len(lines) if oldLines < newLines: # Add lines for i in range(newLines - oldLines): vim.command("normal o") elif newLines < oldLines: # Delete lines del buf[startRow:startRow + oldLines - newLines] for i in range(len(lines)): buf[startRow + i] = lines[i]
def formatBde(fileName, row, col): """ Format the code around the specified 'col' of the specified 'row' in the specified 'fileName' and overwrite the specified 'fileName' if the formatting succeeds. """ with open(fileName, "r+b") as f: m = mmap.mmap(f.fileno(), 0) linePositions = [] def lineSource(r): while len(linePositions) <= r: linePositions.append(m.tell()) m.readline() pos = m.tell() m.seek(linePositions[r]) ret = m.readline()[:-1] m.seek(pos) return ret try: startEnd, lines = bdeformatutil.formatBde(lineSource, row, col) except ValueError as e: print e return 1 # Make sure we have the position of the line after the end line start, end = startEnd while end + 1 >= len(linePositions): m.seek(linePositions[-1]) m.readline() linePositions.append(m.tell()) # Update the file fixed = "\n".join(lines) fixedLen = len(fixed) + 1 # Add a newline at the end startPos = linePositions[start] endPos = linePositions[end + 1] replaceLen = endPos - startPos moveDest = endPos + fixedLen - replaceLen moveSrc = endPos moveSize = m.size() - endPos if fixedLen > replaceLen: # Grow the file, then move m.resize(m.size() + fixedLen - replaceLen) m.move(moveDest, moveSrc, moveSize) elif fixedLen < replaceLen: # Move, then shrink file m.move(moveDest, moveSrc, moveSize) m.resize(m.size() + fixedLen - replaceLen) m.seek(startPos) m.write(fixed) m.write("\n") m.flush() m.close() # Touch the file, so editors detect that it changed os.utime(fileName, None) return 0;