Skip to content

Commit

Permalink
Change CustomMarkers 'null' value
Browse files Browse the repository at this point in the history
Goal: The JS code currently needs to import the CustomMarkers
type/constructor from Types.js. Remove this need so that Main.js can be
the single point of entry, which will make it easier when bundling up
the core with Parcel etc.

Removing the AllowNullLiteral attribute from the CustomMarkers type and
making it a plain record, as well as removing the Option types from that
record, means it can be more easily created in C# code, and created as a
POJO in JS code.

The Option types on the line & block members were also redundant, since
an empty string is also an empty (invalid) value. Empty strings were not
checked-for in addCustomLanguage, leading to a runtime error if they
were supplied.

Now addCustomLanguage is changed to maybeAddCustomLanguage, and it only
adds the language if it has a valid line or block member.
  • Loading branch information
stkb committed Mar 20, 2021
1 parent dfa7506 commit e0b8db5
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 26 deletions.
2 changes: 1 addition & 1 deletion core.test/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ let printFailure (test: Test) (actual: Lines) =
/// Runs a test
let runTest (test: Test) =
let getLine = Func<int,string>(fun i -> if i < test.input.Length then test.input.[i] else null)
let file = { language = test.language; path = ""; getMarkers = Func<CustomMarkers>(fun () -> null) }
let file = {language = test.language; path = ""; getMarkers = Func<CustomMarkers>(fun () -> {line = ""; block = ("","")})}
let edit = Core.rewrap file test.settings test.selections getLine
let actual = applyEdit edit test.input
let arrayEqual (a: 'a[]) (b: 'a[]) = (a.Length = b.Length && not (Seq.exists2 (fun x y -> x <> y) a b))
Expand Down
23 changes: 12 additions & 11 deletions core/Parsing.Documents.fs
Original file line number Diff line number Diff line change
Expand Up @@ -277,15 +277,20 @@ let mutable languages = [
)
]

/// Creates a custom language parser. Also adds it to the list of languages
let private addCustomLanguage name (markers: CustomMarkers) =
/// Creates a custom language parser, if the given CustomMarkers are valid. Also
/// adds it to the list of languages
let private maybeAddCustomLanguage name (markers: CustomMarkers) : Option<Language> =
let escape = System.Text.RegularExpressions.Regex.Escape
let maybeLine = map (line << escape) markers.line
let maybeBlock = map (block << map escape) markers.block
let list = maybe [] List.singleton maybeBlock @ maybe [] List.singleton maybeLine
let isInvalid = String.IsNullOrEmpty
let maybeLine = if isInvalid markers.line then None else Some (line (escape markers.line))
let maybeBlock =
if isInvalid (fst markers.block) || isInvalid (snd markers.block) then None
else Some (block (map escape markers.block))
let list = [maybeBlock; maybeLine] |> List.choose id
if List.isEmpty list then None else
let cl = lang name "" "" (sourceCode list)
languages <- cl :: languages
cl
Some cl

/// Tries to find a known Language for the given File, using its language ID. If
/// that is empty or the default ('plaintext'), it tries using the file's
Expand All @@ -310,9 +315,5 @@ let languageForFile (file: File) : Option<Language> =
let rec select (file: File) : Settings -> TotalParser<string> =
languageForFile file
|> Option.orElseWith
(fun () ->
match file.getMarkers.Invoke() with
| null -> None
| x -> Some (addCustomLanguage file.language x)
)
(fun () -> maybeAddCustomLanguage file.language (file.getMarkers.Invoke()))
|> maybe plainText Language.parser
9 changes: 5 additions & 4 deletions core/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ namespace Rewrap

open System

[<AllowNullLiteral>]
type CustomMarkers(line: Option<string>, block: Option<string * string>) =
member this.line = line
member this.block = block
// Set of comment markers provided by the editor to create a custom language. To
// be valid, either `line` must be a nonempty string or `block` two nonempty
// strings.
type CustomMarkers = { line: string; block : string * string }


/// File language and path. Used to select a parser.
type File = { language: string; path: string; getMarkers: Func<CustomMarkers> }
Expand Down
3 changes: 2 additions & 1 deletion tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,10 @@ function runTests(tests)

try {
const getLine = i => i < input.length ? input[i] : null
const getMarkers = () => ({line: "", block: ["",""]})
const edit =
Core.rewrap
( { language: settings.language, path: '', getMarkers: () => { } }
( { language: settings.language, path: '', getMarkers }
, Object.assign(settings, { column: wrappingColumn })
, selections
, getLine
Expand Down
3 changes: 2 additions & 1 deletion vs/Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public static void StandardWrap(IWpfTextView textView)
{
var textBuffer = textView.TextBuffer;
var snapshot = textBuffer.CurrentSnapshot;
var file = new File(GetLanguage(textBuffer), GetFilePath(textBuffer), () => null);
var noCustomMarkers = new CustomMarkers("", Tuple.Create("", ""));
var file = new File(GetLanguage(textBuffer), GetFilePath(textBuffer), () => noCustomMarkers);
DocState getDocState(ITextSnapshot ss) =>
new DocState(file.path, ss.Version.VersionNumber, GetSelections(textView, ss));

Expand Down
6 changes: 0 additions & 6 deletions vscode/Core.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
const Types = require('./core/Types')
const Main = require('./core/Main')


export interface CustomMarkers { line: string, block: [string, string] }
export interface CustomMarkersStatic {
new(line: string, block: string[]): CustomMarkers
}

export interface DocState { filePath: string, version: number, selections: Selection[] }

Expand Down Expand Up @@ -34,8 +30,6 @@ export interface Settings {
wholeComment: boolean
}

export const CustomMarkers: CustomMarkersStatic = Types.CustomMarkers

/** Gets the current wrapping column used for the given document */
export const getWrappingColumn: (path: string, columns: number[]) => number =
Main.getWrappingColumn
Expand Down
5 changes: 3 additions & 2 deletions vscode/CustomLanguage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const Path = require('path')
const FS = require('fs')
const JSON = require('json5')
const {CustomMarkers} = require('./core/Types')

const getConfig = (getText, path) => {
let config = {line: null, block: null}
Expand Down Expand Up @@ -61,14 +60,16 @@ export default function(exts?, getFileText?) {

getFileText = getFileText || (p => FS.readFileSync(p))
let cache = null
const noMarkers = {line: "", block: ["", ""]}
return lang => {
cache = cache || createCache(exts)

if (typeof cache[lang] === 'string') {
const config = getConfig(getFileText, cache[lang])
cache[lang] = (config.line || config.block) ?
new CustomMarkers(config.line, config.block) : null
{line: config.line, block: config.block} : noMarkers
}
else if (!cache[lang]) cache[lang] = noMarkers
return cache[lang]
}
}

0 comments on commit e0b8db5

Please sign in to comment.