Skip to content

Commit

Permalink
Fix: determine newline characters based on fileformat
Browse files Browse the repository at this point in the history
  • Loading branch information
uga-rosa committed Dec 9, 2023
1 parent 840ac78 commit 06197e4
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 24 deletions.
3 changes: 2 additions & 1 deletion denops/@ddc-sources/denippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
OnCompleteDoneArguments,
} from "https://deno.land/x/[email protected]/base/source.ts";
import { Denops, op } from "../denippet/deps/denops.ts";
import { splitLines } from "../denippet/util.ts";

type Params = Record<PropertyKey, never>;

Expand Down Expand Up @@ -56,7 +57,7 @@ export class Source extends BaseSource<Params> {
return { kind: "empty" };
}
const contents: string[] = await this.snippetToString(denops, userData.denippet.body)
.then((body) => body.replaceAll(/\r\n?/g, "\n").split("\n"))
.then(splitLines)
.catch(() => []);
if (contents.length > 0) {
const filetype = await op.filetype.get(denops);
Expand Down
19 changes: 13 additions & 6 deletions denops/denippet/indent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (c) 2019 hrsh7th

import { Denops, fn, op } from "./deps/denops.ts";
import { splitLines } from "./util.ts";
import { getNewline, splitLines } from "./util.ts";

async function getOneIndent(
denops: Denops,
Expand All @@ -29,6 +29,9 @@ export async function adjustIndent(
denops: Denops,
text: string,
): Promise<string> {
const newline = await getNewline(denops);
text = text.replaceAll(newline, "\n");

const oneIndent = await getOneIndent(denops);
const baseIndent = await getBaseIndent(denops);
if (oneIndent !== "\t") {
Expand All @@ -42,13 +45,16 @@ export async function adjustIndent(
// Remove indentation on all blank lines except the last line.
text = text.replaceAll(/\n\s*\n/g, "\n\n");

return text;
return text.replaceAll(/\n/g, newline);
}

export function trimBaseIndent(
export async function trimBaseIndent(
denops: Denops,
text: string,
): string {
text = text.replaceAll(/\r\n?/g, "\n");
): Promise<string> {
const newline = await getNewline(denops);

text = text.replaceAll(newline, "\n");
const isCharWise = !/\n$/.test(text);
text = text.replace(/\n$/, "");

Expand All @@ -71,5 +77,6 @@ export function trimBaseIndent(
}
});

return text.replaceAll(new RegExp(`(^|\n)${baseIndent}`, "g"), "$1");
return text.replaceAll(new RegExp(`(^|\n)${baseIndent}`, "g"), "$1")
.replaceAll("\n", newline);
}
23 changes: 14 additions & 9 deletions denops/denippet/loader.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Denops } from "./deps/denops.ts";
import { path, TOML, YAML } from "./deps/std.ts";
import { is, u } from "./deps/unknownutil.ts";
import { asyncFilter } from "./util.ts";
import { asyncFilter, getNewline } from "./util.ts";

const isStringOrArray = is.OneOf([is.String, is.ArrayOf(is.String)]);
const isIfKeyword = is.LiteralOneOf(["base", "start", "vimscript", "lua"] as const);
Expand Down Expand Up @@ -69,13 +69,16 @@ function toArray<T>(x: T | T[]): T[] {
return Array.isArray(x) ? x : [x];
}

function toString(x?: string | string[]): string {
function toString(
x: string | string[] | undefined,
newline: string,
): string {
if (x == null) {
return "";
} else if (is.String(x)) {
return x;
} else {
return x.join("\n");
return x.join(newline);
}
}

Expand Down Expand Up @@ -132,9 +135,10 @@ export class Loader {
filepath: string,
filetype: string | string[],
): Promise<void> {
const extension = filepath.split(".").pop()!;
const newline = await getNewline(this.denops);
let snippets: NormalizedSnippet[] = [];

const extension = filepath.split(".").pop()!;
if (extension === "ts") {
const content = await import(path.toFileUrl(filepath).toString())
.then((module) => module.snippets);
Expand All @@ -146,9 +150,10 @@ export class Loader {
body: async (denops: Denops) => {
return toString(
typeof snip.body == "function" ? await snip.body(denops) : snip.body,
newline,
);
},
description: toString(snip.description),
description: toString(snip.description, newline),
}));
} else {
const raw = await Deno.readTextFile(filepath);
Expand All @@ -163,8 +168,8 @@ export class Loader {
...snip,
name,
prefix: toArray(snip.prefix ?? name),
body: toString(snip.body),
description: toString(snip.description),
body: toString(snip.body, newline),
description: toString(snip.description, newline),
}));
} else if (extension === "code-snippets") {
const content = JSON.parse(raw);
Expand All @@ -175,8 +180,8 @@ export class Loader {
...snippet,
name,
prefix: toArray(snippet.prefix ?? name),
body: toString(snippet.body),
description: toString(snippet.description),
body: toString(snippet.body, newline),
description: toString(snippet.description, newline),
};
this.set(ft, [snip]);
}
Expand Down
4 changes: 2 additions & 2 deletions denops/denippet/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { lsputil } from "./deps/lsp.ts";
import { Loader, NormalizedSnippet } from "./loader.ts";
import { Session } from "./session.ts";
import { register } from "./variable.ts";
import { echoerr } from "./util.ts";
import { echoerr, getNewline } from "./util.ts";
import { UserData } from "../@ddc-sources/denippet.ts";

type CompleteItem = {
Expand Down Expand Up @@ -105,7 +105,7 @@ export function main(denops: Denops): void {
async anonymous(bodyU: unknown, prefixU: unknown): Promise<void> {
let body = u.ensure(bodyU, is.OneOf([is.String, is.ArrayOf(is.String)]));
if (is.ArrayOf(is.String)(body)) {
body = body.join("\n");
body = body.join(await getNewline(denops));
}
const prefix = u.ensure(prefixU, is.OptionalOf(is.String));
if (await session.expand(body, prefix)) {
Expand Down
5 changes: 3 additions & 2 deletions denops/denippet/node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Denops } from "./deps/denops.ts";
import { LSP, lsputil } from "./deps/lsp.ts";
import { camelcase } from "./deps/camelcase.ts";
import { splitLines } from "./util.ts";
import { getNewline, splitLines } from "./util.ts";
import * as V from "./variable.ts";
import { clearExtmark, getExtmarks, setExtmark } from "./extmark.ts";

Expand Down Expand Up @@ -136,7 +136,8 @@ export abstract class Jumpable extends Node {
this.range = await lsputil.toUtf16Range(this.denops, 0, range8, "utf-8");
}
const lines = await lsputil.getText(this.denops, 0, this.range);
this.input = lines.join("\n");
const newline = await getNewline(this.denops);
this.input = lines.join(newline);
}

async updateRange(
Expand Down
9 changes: 7 additions & 2 deletions denops/denippet/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { batch, Denops } from "./deps/denops.ts";
import { batch, Denops, op } from "./deps/denops.ts";
import { LSP, lsputil } from "./deps/lsp.ts";
import { getExtmarks, setExtmark } from "./extmark.ts";

Expand All @@ -21,7 +21,12 @@ export async function asyncFilter<T>(
return array.filter((_, i) => bits[i]);
}

export function splitLines(text: string): [string, ...string[]] {
export async function getNewline(denops: Denops): Promise<string> {
const ff = await op.fileformat.get(denops);
return ff === "unix" ? "\n" : ff === "dos" ? "\r\n" : "\r";
}

export function splitLines(text: string): string[] {
return text.replaceAll(/\r\n?/g, "\n").split("\n") as [string, ...string[]];
}

Expand Down
4 changes: 2 additions & 2 deletions denops/denippet/variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function call(
/** The currently selected text or the empty string */
register("TM_SELECTED_TEXT", async (denops) => {
const text = await fn.getreg(denops, `"`) as string;
return trimBaseIndent(text);
return await trimBaseIndent(denops, text);
});

/** The contents of the current line */
Expand Down Expand Up @@ -79,7 +79,7 @@ register("RELATIVE_FILEPATH", async (denops) => {
register("CLIPBOARD", async (denops, text) => {
const clipboard = await fn.getreg(denops) as string;
if (is.String(clipboard)) {
return trimBaseIndent(clipboard);
return await trimBaseIndent(denops, clipboard);
}
return text;
});
Expand Down

0 comments on commit 06197e4

Please sign in to comment.