-
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add auto-highlighting of selected/updated code
- Loading branch information
1 parent
5df4587
commit b789250
Showing
39 changed files
with
1,162 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,38 @@ | ||
import { CodeChangedEvent } from './Event/CodeChangedEvent'; | ||
import { CodePosition } from './Position/CodePosition'; | ||
import { ICodeChangedEvent } from './Event/ICodeChangedEvent'; | ||
import { SelectedScript } from '@/application/State/Selection/SelectedScript'; | ||
import { IUserSelection } from '@/application/State/Selection/IUserSelection'; | ||
import { UserScriptGenerator } from './UserScriptGenerator'; | ||
import { UserScriptGenerator } from './Generation/UserScriptGenerator'; | ||
import { Signal } from '@/infrastructure/Events/Signal'; | ||
import { IApplicationCode } from './IApplicationCode'; | ||
import { IUserScriptGenerator } from './IUserScriptGenerator'; | ||
import { IUserScriptGenerator } from './Generation/IUserScriptGenerator'; | ||
|
||
export class ApplicationCode implements IApplicationCode { | ||
public readonly changed = new Signal<string>(); | ||
public readonly changed = new Signal<ICodeChangedEvent>(); | ||
public current: string; | ||
|
||
private readonly generator: IUserScriptGenerator = new UserScriptGenerator(); | ||
private scriptPositions = new Map<SelectedScript, CodePosition>(); | ||
|
||
constructor( | ||
userSelection: IUserSelection, | ||
private readonly version: string) { | ||
private readonly version: string, | ||
private readonly generator: IUserScriptGenerator = new UserScriptGenerator()) { | ||
if (!userSelection) { throw new Error('userSelection is null or undefined'); } | ||
if (!version) { throw new Error('version is null or undefined'); } | ||
this.generator = new UserScriptGenerator(); | ||
if (!generator) { throw new Error('generator is null or undefined'); } | ||
this.setCode(userSelection.selectedScripts); | ||
userSelection.changed.on((scripts) => { | ||
this.setCode(scripts); | ||
}); | ||
} | ||
|
||
private setCode(scripts: ReadonlyArray<SelectedScript>) { | ||
this.current = scripts.length === 0 ? '' : this.generator.buildCode(scripts, this.version); | ||
this.changed.notify(this.current); | ||
private setCode(scripts: ReadonlyArray<SelectedScript>): void { | ||
const oldScripts = Array.from(this.scriptPositions.keys()); | ||
const code = this.generator.buildCode(scripts, this.version); | ||
this.current = code.code; | ||
this.scriptPositions = code.scriptPositions; | ||
const event = new CodeChangedEvent(code.code, oldScripts, code.scriptPositions); | ||
this.changed.notify(event); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { ICodeChangedEvent } from './ICodeChangedEvent'; | ||
import { SelectedScript } from '../../Selection/SelectedScript'; | ||
import { IScript } from '@/domain/IScript'; | ||
import { ICodePosition } from '@/application/State/Code/Position/ICodePosition'; | ||
|
||
export class CodeChangedEvent implements ICodeChangedEvent { | ||
public readonly code: string; | ||
public readonly addedScripts: ReadonlyArray<IScript>; | ||
public readonly removedScripts: ReadonlyArray<IScript>; | ||
public readonly changedScripts: ReadonlyArray<IScript>; | ||
|
||
private readonly scripts: Map<IScript, ICodePosition>; | ||
|
||
constructor( | ||
code: string, | ||
oldScripts: ReadonlyArray<SelectedScript>, | ||
scripts: Map<SelectedScript, ICodePosition>) { | ||
ensureAllPositionsExist(code, Array.from(scripts.values())); | ||
this.code = code; | ||
const newScripts = Array.from(scripts.keys()); | ||
this.addedScripts = selectIfNotExists(newScripts, oldScripts); | ||
this.removedScripts = selectIfNotExists(oldScripts, newScripts); | ||
this.changedScripts = getChangedScripts(oldScripts, newScripts); | ||
this.scripts = new Map<IScript, ICodePosition>(); | ||
scripts.forEach((position, selection) => { | ||
this.scripts.set(selection.script, position); | ||
}); | ||
} | ||
|
||
public isEmpty(): boolean { | ||
return this.scripts.size === 0; | ||
} | ||
|
||
public getScriptPositionInCode(script: IScript): ICodePosition { | ||
return this.scripts.get(script); | ||
} | ||
} | ||
|
||
function ensureAllPositionsExist(script: string, positions: ReadonlyArray<ICodePosition>) { | ||
const totalLines = script.split(/\r\n|\r|\n/).length; | ||
for (const position of positions) { | ||
if (position.endLine > totalLines) { | ||
throw new Error(`script end line (${position.endLine}) is out of range.` + | ||
`(total code lines: ${totalLines}`); | ||
} | ||
} | ||
} | ||
|
||
function getChangedScripts( | ||
oldScripts: ReadonlyArray<SelectedScript>, | ||
newScripts: ReadonlyArray<SelectedScript>): ReadonlyArray<IScript> { | ||
return newScripts | ||
.filter((newScript) => oldScripts.find((oldScript) => oldScript.id === newScript.id | ||
&& oldScript.revert !== newScript.revert )) | ||
.map((selection) => selection.script); | ||
} | ||
|
||
function selectIfNotExists( | ||
selectableContainer: ReadonlyArray<SelectedScript>, | ||
test: ReadonlyArray<SelectedScript>) { | ||
return selectableContainer | ||
.filter((script) => !test.find((oldScript) => oldScript.id === script.id)) | ||
.map((selection) => selection.script); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { IScript } from '@/domain/IScript'; | ||
import { ICodePosition } from '@/application/State/Code/Position/ICodePosition'; | ||
|
||
export interface ICodeChangedEvent { | ||
readonly code: string; | ||
addedScripts: ReadonlyArray<IScript>; | ||
removedScripts: ReadonlyArray<IScript>; | ||
changedScripts: ReadonlyArray<IScript>; | ||
isEmpty(): boolean; | ||
getScriptPositionInCode(script: IScript): ICodePosition; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { SelectedScript } from '@/application/State/Selection/SelectedScript'; | ||
import { ICodePosition } from '@/application/State/Code/Position/ICodePosition'; | ||
|
||
export interface IUserScript { | ||
code: string; | ||
scriptPositions: Map<SelectedScript, ICodePosition>; | ||
} |
6 changes: 4 additions & 2 deletions
6
src/application/State/Code/Generation/IUserScriptGenerator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import { SelectedScript } from '@/application/State/Selection/SelectedScript'; | ||
|
||
import { IUserScript } from './IUserScript'; | ||
export interface IUserScriptGenerator { | ||
buildCode(selectedScripts: ReadonlyArray<SelectedScript>, version: string): string; | ||
buildCode( | ||
selectedScripts: ReadonlyArray<SelectedScript>, | ||
version: string): IUserScript; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import { ICodeChangedEvent } from './Event/ICodeChangedEvent'; | ||
import { ISignal } from '@/infrastructure/Events/ISignal'; | ||
|
||
export interface IApplicationCode { | ||
readonly changed: ISignal<string>; | ||
readonly changed: ISignal<ICodeChangedEvent>; | ||
readonly current: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ICodePosition } from './ICodePosition'; | ||
export class CodePosition implements ICodePosition { | ||
|
||
public get totalLines(): number { | ||
return this.endLine - this.startLine; | ||
} | ||
|
||
constructor( | ||
public readonly startLine: number, | ||
public readonly endLine: number) { | ||
if (startLine < 0) { | ||
throw new Error('Code cannot start in a negative line'); | ||
} | ||
if (endLine < 0) { | ||
throw new Error('Code cannot end in a negative line'); | ||
} | ||
if (endLine === startLine) { | ||
throw new Error('Empty code'); | ||
} | ||
if (endLine < startLine) { | ||
throw new Error('End line cannot be less than start line'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export interface ICodePosition { | ||
readonly startLine: number; | ||
readonly endLine: number; | ||
readonly totalLines: number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.