From 84b96ace5eddc0cf557f667e90041f00ce2caef4 Mon Sep 17 00:00:00 2001
From: itdominator <1itdominator@gmail.com>
Date: Sat, 6 Apr 2024 23:50:50 -0500
Subject: [PATCH] Wiring Search/Replace UI
---
.../search_replace/styling_mixin.py | 2 +-
.../usr/share/newton/context_path/index.html | 55 +++--
.../resources/css/newton/main.css | 20 ++
.../resources/css/newton/overrides.css | 10 +
.../resources/js/newton/components.js | 225 +++++++++++++++++-
.../resources/js/newton/events.js | 16 +-
.../resources/js/newton/globals.js | 6 +
.../resources/js/newton/keybinding-newton.js | 5 +-
.../resources/js/newton/ui-logic.js | 37 +--
9 files changed, 311 insertions(+), 65 deletions(-)
diff --git a/plugins/gtksourceview/search_replace/styling_mixin.py b/plugins/gtksourceview/search_replace/styling_mixin.py
index 1baf8a5..3336bec 100644
--- a/plugins/gtksourceview/search_replace/styling_mixin.py
+++ b/plugins/gtksourceview/search_replace/styling_mixin.py
@@ -63,4 +63,4 @@ class StylingMixin:
plural = "s" if total_count > 1 else ""
if total_count == 0: self.update_style(2)
- self._find_status_lbl.set_label(f"{count} results{plural} found for '{query}'")
+ self._find_status_lbl.set_label(f"{count} result{plural} found for '{query}'")
diff --git a/user_config/usr/share/newton/context_path/index.html b/user_config/usr/share/newton/context_path/index.html
index 63f8ffb..430591d 100644
--- a/user_config/usr/share/newton/context_path/index.html
+++ b/user_config/usr/share/newton/context_path/index.html
@@ -123,17 +123,15 @@
-
-
@@ -141,34 +139,43 @@
-
- Find All
- Find
+ Find
+ Find All
-
-
-
-
-
-
Replace All
-
Replace
+
+
+
+ Replace
+ Replace All
+
+
diff --git a/user_config/usr/share/newton/context_path/resources/css/newton/main.css b/user_config/usr/share/newton/context_path/resources/css/newton/main.css
index e0caaa3..f3a34af 100644
--- a/user_config/usr/share/newton/context_path/resources/css/newton/main.css
+++ b/user_config/usr/share/newton/context_path/resources/css/newton/main.css
@@ -172,6 +172,26 @@
font-size: initial;
}
+
+.searching,
+.search-success,
+.search-fail {
+ border-style: solid;
+ color: rgba(125, 125, 125, 1) !important;
+}
+
+.searching {
+ border-color: rgba(0, 225, 225, 0.64) !important;
+}
+.search-success {
+ background: rgba(136, 204, 39, 0.12) !important;
+ border-color: rgba(136, 204, 39, 1) !important;
+}
+.search-fail {
+ background: rgba(170, 18, 18, 0.12) !important;
+ border-color: rgba(200, 18, 18, 1) !important;
+}
+
/* Other message text colors */
.error { color: rgb(170, 18, 18); }
.warning { color: rgb(255, 168, 0); }
diff --git a/user_config/usr/share/newton/context_path/resources/css/newton/overrides.css b/user_config/usr/share/newton/context_path/resources/css/newton/overrides.css
index ad1b63f..81e53b5 100644
--- a/user_config/usr/share/newton/context_path/resources/css/newton/overrides.css
+++ b/user_config/usr/share/newton/context_path/resources/css/newton/overrides.css
@@ -13,6 +13,16 @@ ul, li {
list-style: none;
}
+input.form-control,
+input.form-control:focus,
+input.form-control::after,
+input.form-control::placeholder {
+ background-color: rgba(0, 0, 0, 0.0) !important;
+ color: rgba(255, 255, 255, 1.0) !important;
+ /*text-shadow: 0px 0px 0px black !important;*/
+ box-shadow: none !important;
+}
+
.modal-header,
.modal-footer {
background-color: rgba(0, 0, 0, 0.64);
diff --git a/user_config/usr/share/newton/context_path/resources/js/newton/components.js b/user_config/usr/share/newton/context_path/resources/js/newton/components.js
index 61f85e5..bc4173f 100644
--- a/user_config/usr/share/newton/context_path/resources/js/newton/components.js
+++ b/user_config/usr/share/newton/context_path/resources/js/newton/components.js
@@ -175,6 +175,13 @@ class InputCheckboxContainer extends HTMLElement {
}
}
+const QueryState = {
+ Searching: 0,
+ SearchSuccess: 1,
+ SearchFail: 2
+}
+
+
class SearchReplaceContainer extends HTMLElement {
constructor() {
super();
@@ -186,16 +193,232 @@ class SearchReplaceContainer extends HTMLElement {
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild( templateContent.cloneNode(true) );
+ this.showing = false;
}
loadSignals() {
+ this.bindToggleSignal( this.shadowRoot.getElementById("whole-word-btn") );
+ this.bindToggleSignal( this.shadowRoot.getElementById("only-in-selection-btn") );
+ this.bindToggleSignal( this.shadowRoot.getElementById("match-case-btn") );
+ this.bindToggleSignal( this.shadowRoot.getElementById("use-regex-btn") );
+
let elm = this.shadowRoot.getElementById("find-entry");
elm.addEventListener("keyup", (eve) => {
- findEntry(eve.value);
+ if (eve.key === "Enter") {
+ let elm = this.shadowRoot.getElementById("find-btn");
+ elm.click();
+ return
+ }
+
+ let elm = this.shadowRoot.getElementById("find-all-btn");
+ elm.click();
+ });
+
+
+ elm = this.shadowRoot.getElementById("find-btn");
+ elm.addEventListener("click", (eve) => {
+ this.findEntry( this.getQuery() );
+ });
+
+ elm = this.shadowRoot.getElementById("find-all-btn");
+ elm.addEventListener("click", (eve) => {
+ this.findAllEntries( this.getQuery() );
+ });
+
+ elm = this.shadowRoot.getElementById("replace-btn");
+ elm.addEventListener("click", (eve) => {
+ this.findEntry( this.getQuery() );
+ this.replaceEntry( this.getreplacer() );
+ });
+
+ elm = this.shadowRoot.getElementById("replace-all-btn");
+ elm.addEventListener("click", (eve) => {
+ this.findEntry( this.getQuery() );
+ this.replaceAll( this.getreplacer() );
});
}
+ bindToggleSignal(elm) {
+ elm.addEventListener("click", (eve) => {
+ let elm = eve.target.nodeName === "IMG" ? eve.target.parentElement : eve.target;
+ let isActive = elm.classList.contains("btn-info");
+
+ if (isActive) {
+ elm.classList.remove("btn-info");
+ elm.classList.add("btn-dark");
+ } else {
+ elm.classList.add("btn-info");
+ elm.classList.remove("btn-dark")
+ }
+
+ this.setFindOptionsLbl();
+ });
+ }
+
+ toggleShow() {
+ if (this.showing) {
+ this.showing = false;
+ $('#bottom-gutter').popover('hide');
+ } else {
+ this.showing = true;
+ $('#bottom-gutter').popover('show');
+ }
+
+ setTimeout(() => {
+ if (this.showing) {
+ let elm = this.shadowRoot.getElementById("find-entry");
+ elm.focus();
+ } else {
+ editor.focus();
+ }
+ }, 0.5);
+ }
+
+ findPreviousEntry(query) {
+ editor.findPrevious();
+ }
+
+ replaceEntry(toStr) {
+ editor.replace(toStr);
+ }
+
+ replaceAll(toStr) {
+ editor.replaceAll(toStr);
+ }
+
+ findNextEntry(query) {
+ editor.findNext();
+ }
+
+ findAllEntries(query = null, isBackwwards = true, isWrap = true, range = null) {
+ this.updateStyle(QueryState.SearchSuccess);
+ if (query === "") {
+ this.shadowRoot.getElementById("find-status-lbl").innerText = "Find in current buffer";
+ this.updateStyle(QueryState.Searching);
+ this.clearSearchMarkers();
+
+ return;
+ }
+
+ let totalCount = editor.findAll(query, {
+ backwards: isBackwwards === "True" ? true : false,
+ wrap: isWrap === "True" ? true : false,
+ caseSensitive: this.isMatchCase(),
+ wholeWord: this.isUseWholeWord(),
+ regExp: this.isUseRegex(),
+ range: range === "True" ? true : false
+ });
+
+ if (totalCount === 0) {
+ console.log('Empty search result...');
+ this.clearSearchMarkers();
+ }
+
+ this.updateStatusLbl(totalCount, query);
+
+ return totalCount;
+ }
+
+ clearSearchMarkers() {
+ let markers = session.getMarkers(false);
+ for (var id in markers) {
+ if (
+ markers[id].clazz.indexOf("ace_selection") === 0 ||
+ markers[id].clazz.indexOf("ace_selected-word") === 0
+ ) {
+ session.removeMarker(id);
+ }
+ }
+ }
+
+ findEntry(query = null, isBackwwards = true, isWrap = true, range = null) {
+ let result = editor.find(query, {
+ backwards: isBackwwards === "True" ? true : false,
+ wrap: isWrap === "True" ? true : false,
+ caseSensitive: this.isMatchCase(),
+ wholeWord: this.isUseWholeWord(),
+ regExp: this.isUseRegex(),
+ range: range === "True" ? true : false
+ });
+
+ return result;
+ }
+
+ updateStatusLbl(totalCount = 0, query = "") {
+ if ( !query ) return;
+
+ let count = (totalCount > 0) ? totalCount : "No";
+ let plural = (totalCount > 1) ? "s" : "";
+
+ if (totalCount === 0)
+ this.updateStyle(QueryState.SearchFail);
+
+ const statusLbl = `${count} result${plural} found for '${query}'`;
+ this.shadowRoot.getElementById("find-status-lbl").innerText = statusLbl;
+ }
+
+ setFindOptionsLbl() {
+ let findOptions = "Finding with Options: ";
+
+ if ( this.isUseRegex() )
+ findOptions += "Regex";
+
+ findOptions += ( this.isUseRegex() ) ? ", " : "";
+ findOptions += ( this.isMatchCase() ) ? "Case Sensitive" : "Case Inensitive";
+
+ if ( this.isSelectionSearchOnly() )
+ findOptions += ", Within Current Selection";
+
+ if ( this.isUseWholeWord() )
+ findOptions += ", Whole Word";
+
+ this.shadowRoot.getElementById("find-options-lbl").innerText = findOptions;
+ }
+
+ updateStyle(state) {
+ let elm = this.shadowRoot.getElementById("find-entry");
+
+ elm.classList.remove("searching")
+ elm.classList.remove("search-success")
+ elm.classList.remove("search-fail")
+
+ if (state === 0)
+ elm.classList.add("searching");
+ else if (state === 1)
+ elm.classList.add("search-success");
+ else if (state === 2)
+ elm.classList.add("search-fail");
+ }
+
+
+ getQuery() {
+ return this.shadowRoot.getElementById("find-entry").value;
+ }
+
+ getreplacer() {
+ return this.shadowRoot.getElementById("replace-entry").value;
+ }
+
+ isUseWholeWord() {
+ let elm = this.shadowRoot.getElementById("whole-word-btn");
+ return elm.classList.contains("btn-info");
+ }
+
+ isSelectionSearchOnly() {
+ let elm = this.shadowRoot.getElementById("only-in-selection-btn");
+ return elm.classList.contains("btn-info");
+ }
+
+ isMatchCase() {
+ let elm = this.shadowRoot.getElementById("match-case-btn");
+ return elm.classList.contains("btn-info");
+ }
+
+ isUseRegex() {
+ let elm = this.shadowRoot.getElementById("use-regex-btn");
+ return elm.classList.contains("btn-info");
+ }
}
diff --git a/user_config/usr/share/newton/context_path/resources/js/newton/events.js b/user_config/usr/share/newton/context_path/resources/js/newton/events.js
index 4cae356..c13cbf3 100644
--- a/user_config/usr/share/newton/context_path/resources/js/newton/events.js
+++ b/user_config/usr/share/newton/context_path/resources/js/newton/events.js
@@ -37,8 +37,8 @@ const loadLSPClientJSFiles = () => {
}
const loadSearchFind = () => {
- let elm = document.createElement("search-replace");
- let options = {container: "html", content: elm, html: true};
+ searchReplace = document.createElement("search-replace");
+ let options = {container: "html", content: searchReplace, html: true};
$('#bottom-gutter').popover(options);
}
@@ -57,6 +57,11 @@ window.onerror = function(msg, url, line, col, error) {
document.addEventListener("keyup", (eve) => {
+ if (blockHigherNewtonEvePropigation) {
+ blockHigherNewtonEvePropigation = false;
+ return;
+ }
+
switch (eve.key) {
case "ArrowUp":
setLabels();
@@ -96,6 +101,11 @@ document.addEventListener("keyup", (eve) => {
}
}
break;
+ case "f":
+ if (searchReplace.showing) {
+ searchReplace.toggleShow();
+ }
+ break
default:
setLabels();
break
@@ -104,6 +114,8 @@ document.addEventListener("keyup", (eve) => {
document.addEventListener("keydown", (eve) => {
+ if (blockHigherNewtonEvePropigation) return;
+
switch (eve.key) {
case "ArrowUp":
if ( isNotNullOrUndefined(previewSel) ) {
diff --git a/user_config/usr/share/newton/context_path/resources/js/newton/globals.js b/user_config/usr/share/newton/context_path/resources/js/newton/globals.js
index e109bde..049c6dc 100644
--- a/user_config/usr/share/newton/context_path/resources/js/newton/globals.js
+++ b/user_config/usr/share/newton/context_path/resources/js/newton/globals.js
@@ -2,6 +2,7 @@ const messenger = (window.webkit) ? window.webkit.messageHandlers : (message) =
console.log("Message: " + message);
};
+
const EDITOR_OPTS = {
printMarginColumn: 80,
enableBasicAutocompletion: true,
@@ -17,6 +18,7 @@ const EDITOR_OPTS = {
mergeUndoDeltas: false
}
+
const BASE_LINK = `${window.location.href}resources/js/libs/ace_editor/lsp`;
const LSP_SERVER_CONFG = `${window.location.href}../lsp-servers-config.json`;
const BASE_LSP_LINK = "http://0.0.0.0:4880";
@@ -27,6 +29,7 @@ let lspServersConfig = null;
let lspSettingsUI = document.getElementById('lsp-settings');
+let searchReplace = null;
let editor = null;
let previewEditor = null;
let aceSessions = {};
@@ -36,3 +39,6 @@ let fontSize = 12;
let highlightLine = true;
let isControlDown = false;
let queryMarkers = [];
+
+
+let blockHigherNewtonEvePropigation = false;
\ No newline at end of file
diff --git a/user_config/usr/share/newton/context_path/resources/js/newton/keybinding-newton.js b/user_config/usr/share/newton/context_path/resources/js/newton/keybinding-newton.js
index d4b92e9..e712fe2 100644
--- a/user_config/usr/share/newton/context_path/resources/js/newton/keybinding-newton.js
+++ b/user_config/usr/share/newton/context_path/resources/js/newton/keybinding-newton.js
@@ -29,9 +29,8 @@ const editorCommands = [
name: "search",
bindKey: {win: "ctrl-f", mac: "ctrl-f"},
exec: function(editor) {
- // let selectedStr = session.doc.getTextRange(editor.getSelectionRange());
- $('#bottom-gutter').popover('toggle')
- // sendMessage("tggl_search_replace", "", "", "", selectedStr);
+ blockHigherNewtonEvePropigation = true;
+ searchReplace.toggleShow();
},
readOnly: true
}, {
diff --git a/user_config/usr/share/newton/context_path/resources/js/newton/ui-logic.js b/user_config/usr/share/newton/context_path/resources/js/newton/ui-logic.js
index 526a7d5..89f4406 100644
--- a/user_config/usr/share/newton/context_path/resources/js/newton/ui-logic.js
+++ b/user_config/usr/share/newton/context_path/resources/js/newton/ui-logic.js
@@ -221,40 +221,6 @@ const setLabels = () => {
}
-const findEntry = (query = null, isBackwwards = true, isWrap = true,
- isCaseSensitive = false,
- useWholeWord = false,
- useRegExp = false,
- range = null) => {
- // if ( isNotNullOrUndefined(queryMarkers) ) {
- // for (let i = 0; i < queryMarkers.length; i++) {
- // delete queryMarkers[i];
- // }
- // }
-
- // let result = editor.find(query, {
- // backwards: isBackwwards === "True" ? true : false,
- // wrap: isWrap === "True" ? true : false,
- // caseSensitive: isCaseSensitive === "True" ? true : false,
- // wholeWord: useWholeWord === "True" ? true : false,
- // regExp: useRegExp === "True" ? true : false,
- // range: range === "True" ? true : false
- // });
-
- let result = editor.findAll(query, {
- caseSensitive: isCaseSensitive === "True" ? true : false,
- wholeWord: useWholeWord === "True" ? true : false,
- regExp: useRegExp === "True" ? true : false,
- });
-
- console.log(result)
- // if ( isNotNullOrUndefined(result) ) {
- // for (let i = 0; i < result.length; i++) {
- // loadMarker( result[i] );
- // }
- // }
-}
-
const loadMarker = (r) => {
var range = new Range(rowStart, columnStart, rowEnd, columnEnd);
@@ -264,6 +230,9 @@ const loadMarker = (r) => {
}
+const findAllEntries = (query) => {
+ editor.findAll();
+}
const findNextEntry = (query) => {
editor.findNext();