Skip to content

Commit

Permalink
Highlight suggestion of selected cell
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Nov 27, 2024
1 parent c9556c6 commit 28a2f39
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 11 deletions.
8 changes: 7 additions & 1 deletion packages/base/src/suggestionsPanel/cellWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class CellWidget extends Panel {
super(options);
const { cellModel } = options;
this.addClass(suggestionCellStyle);

this._cellId = cellModel.id as string | undefined;
const editorExtensions = () => {
const themes = new EditorThemeRegistry();
EditorThemeRegistry.getDefaultThemes().forEach(theme => {
Expand Down Expand Up @@ -106,6 +106,12 @@ export class CellWidget extends Panel {
}).initializeState();
this.addWidget(cellWidget);
}

get cellId(): string | undefined {
return this._cellId;
}

private _cellId: string | undefined;
}

export namespace CellWidget {
Expand Down
4 changes: 2 additions & 2 deletions packages/base/src/suggestionsPanel/cmExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class HighlightDiff {
// Highlight added text
decorations.push(
Decoration.mark({
class: 'cm-diff-added'
class: 'cm-cell-diff-added'
}).range(pos, pos + length)
);
pos += length; // Move the position for added text
Expand Down Expand Up @@ -83,7 +83,7 @@ class RemovedTextWidget extends WidgetType {
toDOM() {
const span = document.createElement('span');
span.textContent = this._text;
span.className = 'cm-diff-removed';
span.className = 'cm-cell-diff-removed';
return span;
}

Expand Down
37 changes: 36 additions & 1 deletion packages/base/src/suggestionsPanel/model.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { NotebookPanel } from '@jupyterlab/notebook';
import { Notebook, NotebookPanel } from '@jupyterlab/notebook';
import {
IAllSuggestions,
ISuggestionChange,
ISuggestionsManager,
ISuggestionsModel
} from '../types';
import { ISignal, Signal } from '@lumino/signaling';
import { Cell, ICellModel } from '@jupyterlab/cells';
export class SuggestionsModel implements ISuggestionsModel {
constructor(options: SuggestionsModel.IOptions) {
this.switchNotebook(options.panel);
Expand All @@ -21,6 +22,9 @@ export class SuggestionsModel implements ISuggestionsModel {
get notebookSwitched(): ISignal<ISuggestionsModel, void> {
return this._notebookSwitched;
}
get activeCellChanged(): ISignal<ISuggestionsModel, { cellId?: string }> {
return this._activeCellChanged;
}
get suggestionChanged(): ISignal<
ISuggestionsModel,
Omit<ISuggestionChange, 'notebookPath'>
Expand Down Expand Up @@ -70,11 +74,37 @@ export class SuggestionsModel implements ISuggestionsModel {
await panel.context.ready;
this._allSuggestions = this._suggestionsManager.getAllSuggestions(panel);
}
this._disconnectPanelSignal();
this._notebookPanel = panel;
this._connectPanelSignal();
this._filePath = this._notebookPanel?.context.localPath;
this._notebookSwitched.emit();
}

private _connectPanelSignal() {
if (!this._notebookPanel) {
return;
}
this._notebookPanel.content.activeCellChanged.connect(
this._handleActiveCellChanged,
this
);
}

private _disconnectPanelSignal() {
if (!this._notebookPanel) {
return;
}
this._notebookPanel.content.activeCellChanged.disconnect(
this._handleActiveCellChanged
);
}
private _handleActiveCellChanged(
nb: Notebook,
cell: Cell<ICellModel> | null
) {
this._activeCellChanged.emit({ cellId: cell?.model.id });
}
private _handleSuggestionChanged(
manager: ISuggestionsManager,
changed: ISuggestionChange
Expand All @@ -84,6 +114,7 @@ export class SuggestionsModel implements ISuggestionsModel {
this._suggestionChanged.emit(newChanged);
}
}

private _isDisposed = false;
private _filePath?: string;
private _notebookPanel: NotebookPanel | null = null;
Expand All @@ -94,6 +125,10 @@ export class SuggestionsModel implements ISuggestionsModel {
ISuggestionsModel,
Omit<ISuggestionChange, 'notebookPath'>
>(this);
private _activeCellChanged = new Signal<
ISuggestionsModel,
{ cellId?: string }
>(this);
}

export namespace SuggestionsModel {
Expand Down
8 changes: 7 additions & 1 deletion packages/base/src/suggestionsPanel/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ export const suggestionsWidgetAreaStyle = style({
});

export const suggestionCellStyle = style({
background: 'var(--jp-cell-editor-background)'
background: 'var(--jp-cell-editor-background)',
margin: '5px'
});
export const suggestionCellSelectedStyle = style({
border:
'var(--jp-border-width) solid var(--jp-cell-editor-active-border-color)',
boxShadow: 'var(--jp-elevation-z4)'
});
31 changes: 27 additions & 4 deletions packages/base/src/suggestionsPanel/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { Panel } from '@lumino/widgets';

import { ISuggestionChange, ISuggestionsModel } from '../types';
import { CellWidget } from './cellWidget';
import { suggestionsWidgetAreaStyle } from './style';
import {
suggestionCellSelectedStyle,
suggestionsWidgetAreaStyle
} from './style';

export class SuggestionsWidget extends PanelWithToolbar {
constructor(options: SuggestionsWidget.IOptions) {
Expand All @@ -15,14 +18,20 @@ export class SuggestionsWidget extends PanelWithToolbar {

this._renderSuggestions();

this._model.notebookSwitched.connect(() => {
this._renderSuggestions();
});
this._model.suggestionChanged.connect(this._updateSuggestions, this);

this._model.notebookSwitched.connect(this._handleNotebookSwitched, this);

this._model.activeCellChanged.connect(this._handleActiveCellChanged, this);
}

dispose(): void {
this._model.suggestionChanged.disconnect(this._updateSuggestions);

this._model.notebookSwitched.disconnect(this._handleNotebookSwitched);

this._model.activeCellChanged.disconnect(this._handleActiveCellChanged);
}
private _updateSuggestions(
_: ISuggestionsModel,
changedArg: Omit<ISuggestionChange, 'notebookPath'>
Expand All @@ -34,6 +43,7 @@ export class SuggestionsWidget extends PanelWithToolbar {
if (suggestion) {
const w = new CellWidget({ cellModel: suggestion.content });
w.id = suggestionId;
w.addClass(suggestionCellSelectedStyle);
this._suggestionsArea.addWidget(w);
}
break;
Expand All @@ -44,6 +54,19 @@ export class SuggestionsWidget extends PanelWithToolbar {
}
}

private _handleActiveCellChanged(
sender: ISuggestionsModel,
args: { cellId?: string }
) {
for (const w of this._suggestionsArea.widgets as CellWidget[]) {
if (w.cellId === args.cellId) {
w.addClass(suggestionCellSelectedStyle);
} else {
w.removeClass(suggestionCellSelectedStyle);
}
}
}

private _handleNotebookSwitched() {
this._renderSuggestions();
}
Expand Down
1 change: 1 addition & 0 deletions packages/base/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface ISuggestionsModel extends IDisposable {
currentNotebookPanel: NotebookPanel | null;
allSuggestions: IAllSuggestions | undefined;
notebookSwitched: ISignal<ISuggestionsModel, void>;
activeCellChanged: ISignal<ISuggestionsModel, { cellId?: string }>;
suggestionChanged: ISignal<
ISuggestionsModel,
Omit<ISuggestionChange, 'notebookPath'>
Expand Down
4 changes: 2 additions & 2 deletions python/jupyter_suggestions_core/style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
*/

/* Added text: Highlighted with green */
.cm-diff-added {
.cm-cell-diff-added {
background-color: rgb(0 255 0 / 30%); /* Light green */
border-radius: 3px;
}

/* Removed text: Strikethrough with red */
.cm-diff-removed {
.cm-cell-diff-removed {
background-color: rgb(255 0 0 / 10%); /* Light red */
text-decoration: line-through;
color: gray;
Expand Down

0 comments on commit 28a2f39

Please sign in to comment.