generated from itdominator/Python-With-Gtk-Template
Wiring Search/Replace UI
This commit is contained in:
parent
8b555991e4
commit
84b96ace5e
|
@ -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}'")
|
||||
|
|
|
@ -123,17 +123,15 @@
|
|||
</div>
|
||||
|
||||
<div class="col col-5 line-height-32px">
|
||||
<button title="Close Panel" class="float-end" onclick="hideSearchReplace()">X</button>
|
||||
<button title="Whole Word" class="float-end">
|
||||
<button title="Close Panel" class="float-end btn btn-sm btn-dark" onclick="hideSearchReplace()">X</button>
|
||||
<button id="whole-word-btn" title="Whole Word" class="float-end btn btn-sm btn-dark">
|
||||
<img src="resources/imgs/whole-word.png" />
|
||||
</button>
|
||||
<button title="Only In Selection" class="float-end">
|
||||
<button id="only-in-selection-btn" title="Only In Selection" class="float-end btn btn-sm btn-dark">
|
||||
<img src="resources/imgs/only-in-selection.png" />
|
||||
</button>
|
||||
<button title="Match Case" class="float-end">Aa</button>
|
||||
|
||||
|
||||
<button title="Use Regex" class="float-end">.*</button>
|
||||
<button id="match-case-btn" title="Match Case" class="float-end btn btn-sm btn-dark">Aa</button>
|
||||
<button id="use-regex-btn" title="Use Regex" class="float-end btn btn-sm btn-dark" btn>.*</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -141,34 +139,43 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input id="find-entry" class="sr-input-expand" type="search"
|
||||
title="Find in current buffer"
|
||||
placeholder="Find in current buffer"
|
||||
/>
|
||||
<div class="input-group-sm mb-3">
|
||||
<input id="find-entry"
|
||||
class="form-control"
|
||||
type="search"
|
||||
placeholder="Find in current buffer"
|
||||
aria-label="Find in current buffer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-auto">
|
||||
<button class="float-end width-8em">Find All</button>
|
||||
<button class="float-end width-8em">Find</button>
|
||||
<button id="find-btn" class="width-8em btn btn-sm btn-dark">Find</button>
|
||||
<button id="find-all-btn" class="width-8em btn btn-sm btn-dark">Find All</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="margin-tb-1em"></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input id="replace-entry" class="sr-input-expand" type="search"
|
||||
title="Replace in current buffer"
|
||||
placeholder="Replace in current buffer"
|
||||
/>
|
||||
</div>
|
||||
<div class="col col-auto">
|
||||
<button class="float-end width-8em">Replace All</button>
|
||||
<button class="float-end width-8em">Replace</button>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="input-group-sm mb-3">
|
||||
<input id="replace-entry"
|
||||
class="form-control"
|
||||
type="search"
|
||||
title="Replace in current buffer"
|
||||
placeholder="Replace in current buffer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-auto">
|
||||
<button id="replace-btn" class="width-8em btn btn-sm btn-dark">Replace</button>
|
||||
<button id="replace-all-btn" class="width-8em btn btn-sm btn-dark">Replace All</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) ) {
|
||||
|
|
|
@ -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;
|
|
@ -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
|
||||
}, {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue