Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/codemirror/extensions/align-assignments.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import * as CodeMirror from "codemirror";6import { cm_start_end } from "./util";78/*9Format the selected block (or blocks) of text, so it looks like this:10stuff : 'abc'11foo : 112more_0 : 'blah'13Or14stuff = 'abc'15foo = 116more_0 = 'blah'17The column separate is the first occurence in the first line of18one of '=' or ':'. Selected lines that don't contain either symbol19are ignored.2021NOTE: This is a nonstandard extension motivated mostly by coffeescript.22**Thus consider it on the way to being deprecated.** Prettier and its23ilk solves the same sort of problem for all the languages we plan to24use longterm in a vastly better way.25*/2627CodeMirror.defineExtension("align_assignments", function () {28// @ts-ignore29const cm : any = this;30for (let sel of cm.listSelections()) {31const { start_line, end_line } = cm_start_end(sel);32let symbol: string | undefined = undefined;33let column = 0;34// first pass -- figure out what the symbol is and what column we will move it to.35for (let n = start_line; n <= end_line; n++) {36const x = cm.getLine(n);37if (symbol == null) {38// we still don't know what the separate symbol is.39if (x.indexOf(":") != -1) {40symbol = ":";41} else if (x.indexOf("=") != -1) {42symbol = "=";43}44}45let i = x.indexOf(symbol);46if (i === -1) {47continue; // no symbol in this line, so skip48}49// reduce i until x[i-1] is NOT whitespace.50while (i > 0 && x[i - 1].trim() === "") {51i -= 1;52}53i += 1;54column = Math.max(i, column);55}56if (symbol == null || !column) {57continue; // no symbol in this selection, or no need to move it. Done.58}59// second pass -- move symbol over by inserting space60for (let n = start_line; n <= end_line; n++) {61const x = cm.getLine(n);62const i = x.indexOf(symbol);63if (i !== -1) {64// There is a symbol in this line -- put it in the spot where we want it.65if (i < column) {66// symbol is too early -- add space67// column - i spaces68let spaces = "";69for (let j = 0; j < column - i; j++) {70spaces += " ";71}72// insert spaces in front of the symbol73cm.replaceRange(spaces, { line: n, ch: i }, { line: n, ch: i });74} else if (i > column) {75// symbol is too late -- remove spaces76cm.replaceRange("", { line: n, ch: column }, { line: n, ch: i });77}78// Ensure the right amount of whitespace after the symbol -- exactly one space79let j = i + 1; // this will be the next position after x[i] that is not whitespace80while (j < x.length && x[j].trim() === "") {81j += 1;82}83if (j - i >= 2) {84// remove some spaces85cm.replaceRange(86"",87{ line: n, ch: column + 1 },88{ line: n, ch: column + (j - i - 1) }89);90} else if (j - i === 1) {91// insert a space92cm.replaceRange(93" ",94{ line: n, ch: column + 1 },95{ line: n, ch: column + 1 }96);97}98}99}100}101});102103104