Skip to content
Merged

Dev1 #106

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
#
# dist build output
target/

# CodeChat Editor lexer: python. See TODO.
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@ Changelog

* No changes.

Version 0.1.51 -- 2025-Feb-18
Version 0.1.52 -- 2026-Apr-09
-----------------------------

* Fix losing last typed character when receiving a translation while a TinyMCE
edit is pending.
* Avoid unnecessary and distracting scrolling to the top of a doc block when
focusing the doc block.
* When first switching to a file, restore the cursor position from VSCode.

Version 0.1.51 -- 2026-Feb-18
-----------------------------

* Revert back to working version of CodeMirror.
* Updates to other libraries.

Version 0.1.50 -- 2025-Feb-05
Version 0.1.50 -- 2026-Feb-05
-----------------------------

* First and second-level heading underlines are now sized based on the heading's
Expand Down
12 changes: 6 additions & 6 deletions client/package.json5
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
url: 'https://github.com/bjones1/CodeChat_editor',
},
type: 'module',
version: '0.1.51',
version: '0.1.52',
dependencies: {
'@codemirror/commands': '^6.10.3',
'@codemirror/lang-cpp': '^6.0.3',
Expand Down Expand Up @@ -77,13 +77,13 @@
'@types/dom-navigation': '^1.0.7',
'@types/js-beautify': '^1.14.3',
'@types/mocha': '^10.0.10',
'@types/node': '^24.12.0',
'@types/node': '^24.12.2',
'@types/toastify-js': '^1.12.4',
'@typescript-eslint/eslint-plugin': '^8.58.0',
'@typescript-eslint/parser': '^8.58.0',
'@typescript-eslint/eslint-plugin': '^8.58.1',
'@typescript-eslint/parser': '^8.58.1',
chai: '^6.2.2',
esbuild: '^0.28.0',
eslint: '^10.1.0',
eslint: '^10.2.0',
'eslint-config-prettier': '^10.1.8',
'eslint-plugin-import': '^2.32.0',
'eslint-plugin-prettier': '^5.5.5',
Expand All @@ -92,7 +92,7 @@
'npm-check-updates': '^20.0.0',
prettier: '^3.8.1',
typescript: '^6.0.2',
'typescript-eslint': '^8.58.0',
'typescript-eslint': '^8.58.1',
},
scripts: {
test: 'echo "Error: no test specified" && exit 1',
Expand Down
476 changes: 235 additions & 241 deletions client/pnpm-lock.yaml

Large diffs are not rendered by default.

32 changes: 19 additions & 13 deletions client/src/CodeChatEditor.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// [http://www.gnu.org/licenses](http://www.gnu.org/licenses).
//
// `CodeChatEditor.mts` -- the CodeChat Editor Client
// =============================================================================
// ==================================================
//
// The overall process of load a file is:
//
Expand All @@ -39,7 +39,7 @@
// writes this code to the disk.
//
// Imports
// -----------------------------------------------------------------------------
// -------
//
// ### JavaScript/TypeScript
//
Expand Down Expand Up @@ -78,7 +78,7 @@ import { show_toast } from "./show_toast.mjs";
import "./css/CodeChatEditor.css";

// Data structures
// -----------------------------------------------------------------------------
// ---------------
//
// <a id="EditorMode"></a>Define all possible editor modes; these are passed as
// a [query string](https://en.wikipedia.org/wiki/Query_string)
Expand Down Expand Up @@ -119,7 +119,7 @@ declare global {
}

// Globals
// -----------------------------------------------------------------------------
// -------
//
// The ID of the autosave timer; when this timer expires, the document will be
// autosaved.
Expand All @@ -145,7 +145,7 @@ export const set_is_dirty = (value: boolean = true) => {
export const get_is_dirty = () => is_dirty;

// Page initialization
// -----------------------------------------------------------------------------
// -------------------

// This is copied from
// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event#checking_whether_loading_is_already_complete).
Expand All @@ -160,7 +160,7 @@ export const on_dom_content_loaded = (on_load_func: () => void) => {
};

// File handling
// -----------------------------------------------------------------------------
// -------------
//
// True if this is a CodeChat Editor document (not a source file).
const is_doc_only = () => {
Expand All @@ -169,13 +169,13 @@ const is_doc_only = () => {
return current_metadata?.["mode"] === "markdown";
};

// Wait for the DOM to load before opening the file.
const open_lp = async (
codechat_for_web: CodeChatForWeb,
is_re_translation: boolean,
cursor_line?: number,
scroll_line?: number,
) =>
// Wait for the DOM to load before opening the file.
await new Promise<void>((resolve) =>
on_dom_content_loaded(async () => {
await _open_lp(
Expand Down Expand Up @@ -216,10 +216,16 @@ const _open_lp = async (
// render is finished.
await window.MathJax.startup.promise;

// The only the `await` is based on TinyMCE init, which should only cause an
// async delay on its first execution. (Even then, I'm not sure it does,
// since all resources are statically imported). So, we should be OK for the
// rest of this function.
// Process any pending events before proceeding. Sometimes, TinyMCE has a
// pending edit that hasn't been processed yet, meaning the `is_dirty` flag
// is incorrect.
tinymce.activeEditor?.save();
await new Promise((resolve) => setTimeout(resolve, 0));

// The only call to `await` is based on TinyMCE init, which should only
// cause an async delay on its first execution. (Even then, I'm not sure it
// does, since all resources are statically imported). So, we should be OK
// for the rest of this function.
//
// Now, make all decisions about `is_dirty`: if the text is dirty, do some
// special processing; simply applying the update could cause either data
Expand Down Expand Up @@ -561,7 +567,7 @@ const clearAutosaveTimer = () => {
};

// Navigation
// -----------------------------------------------------------------------------
// ----------
//
// The TOC and this page calls this when a hyperlink is clicked. This saves the
// current document before navigating.
Expand Down Expand Up @@ -704,7 +710,7 @@ on_dom_content_loaded(async () => {
});

// Testing
// -----------------------------------------------------------------------------
// -------
//
// A great and simple idea taken from
// [SO](https://stackoverflow.com/a/54116079): wrap all testing exports in a
Expand Down
8 changes: 4 additions & 4 deletions client/src/CodeChatEditorFramework.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// [http://www.gnu.org/licenses](http://www.gnu.org/licenses).
//
// `CodeChatEditorFramework.mts` -- the CodeChat Editor Client Framework
// =============================================================================
// =====================================================================
//
// This maintains a websocket connection between the CodeChat Editor Server. The
// accompanying HTML is a full-screen iframe, allowing the Framework to change
Expand All @@ -24,7 +24,7 @@
// location changes.
//
// Imports
// -----------------------------------------------------------------------------
// -------
//
// ### Third-party
import ReconnectingWebSocket from "./third-party/ReconnectingWebSocket.cjs";
Expand All @@ -49,7 +49,7 @@ import {
import { ResultErrTypes } from "./rust-types/ResultErrTypes.js";

// Websocket
// -----------------------------------------------------------------------------
// ---------
//
// This code communicates with the CodeChat Editor Server via its websocket
// interface.
Expand Down Expand Up @@ -167,7 +167,7 @@ class WebSocketComm {
if (contents !== undefined) {
// Check and update the version. If this is a diff,
// ensure the diff was made against the version of
// the file we have. Ignore re-translation version errors, instead ignoring the update.
// the file we have.
if ("Diff" in contents.source) {
if (
contents.source.Diff.version !==
Expand Down
18 changes: 11 additions & 7 deletions client/src/CodeMirror-integration.mts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
// 5. Define a set of StateEffects to add/update/etc. doc blocks.
//
// Imports
// -----------------------------------------------------------------------------
// -------
//
// ### Third-party
import { basicSetup } from "codemirror";
Expand Down Expand Up @@ -104,7 +104,7 @@ import { assert } from "./assert.mjs";
import { show_toast } from "./show_toast.mjs";

// Globals
// -----------------------------------------------------------------------------
// -------
let current_view: EditorView;
// This indicates that a call to `on_dirty` is scheduled, but hasn't run yet.
let on_dirty_scheduled = false;
Expand Down Expand Up @@ -137,7 +137,7 @@ const exceptionSink = EditorView.exceptionSink.of((exception) => {
});

// Doc blocks in CodeMirror
// -----------------------------------------------------------------------------
// ------------------------
//
// The goal: given a [Range](https://codemirror.net/docs/ref/#state.Range) of
// lines containing a doc block (a delimiter, indent, and contents) residing at
Expand Down Expand Up @@ -648,14 +648,15 @@ const on_dirty = (
});
};

// Handle cursur movement and mouse selection in a doc block.
export const DocBlockPlugin = ViewPlugin.fromClass(
class {
constructor(_view: EditorView) {}
update(update: ViewUpdate) {
// If the editor doesn't have focus, ignore selection changes. This
// avoid the case where cursor movement in the IDE produces
// selection changes in the Client, which then steals focus. TODO:
// with the editor isn't focused, highlight the relevant line or
// when the editor isn't focused, highlight the relevant line or
// something similar.
if (update.selectionSet && update.view.hasFocus) {
// See if the new main selection falls within a doc block.
Expand Down Expand Up @@ -690,7 +691,7 @@ export const DocBlockPlugin = ViewPlugin.fromClass(
return;
}

// TODO: current, posToDom never gives us a doc
// TODO: currently, posToDom never gives us a doc
// block, even when the from/to is correct. So, we
// never get here.
(dom.childNodes[1] as HTMLElement).focus();
Expand Down Expand Up @@ -811,7 +812,10 @@ export const DocBlockPlugin = ViewPlugin.fromClass(
// This process causes TinyMCE to lose focus. Restore
// that. However, this causes TinyMCE to lose the
// selection, which the next bit of code then restores.
tinymce.activeEditor!.focus(false);
// When the doc block is longer than a screen, omitting
// the `preventScroll` parameter causes this to scroll
// to the top of the doc block, which is incorrect.
tinymce_div.focus({ preventScroll: true });

// Copy the selection over to TinyMCE by indexing the
// selection path to find the selected node.
Expand All @@ -825,7 +829,7 @@ export const DocBlockPlugin = ViewPlugin.fromClass(
);

// UI
// -----------------------------------------------------------------------------
// --
//
// There doesn't seem to be any tracking of a dirty/clean flag built into
// CodeMirror v6 (although
Expand Down
28 changes: 14 additions & 14 deletions extensions/VSCode/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion extensions/VSCode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ license = "GPL-3.0-only"
name = "codechat-editor-vscode-extension"
readme = "../README.md"
repository = "https://github.com/bjones1/CodeChat_Editor"
version = "0.1.51"
version = "0.1.52"

[lib]
crate-type = ["cdylib"]
Expand Down
Loading
Loading