feat: added bookmark directories
This commit is contained in:
parent
0135c64bab
commit
a005fa994f
70
app.go
70
app.go
@ -3,8 +3,10 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@ -15,12 +17,24 @@ type App struct {
|
||||
ctx context.Context
|
||||
|
||||
inputList []string
|
||||
|
||||
remeberedPath []string
|
||||
}
|
||||
|
||||
func GetRemeberPath() (string, error) {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/.config/railgun-remeber", homedir), nil
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{
|
||||
inputList: []string{},
|
||||
inputList: []string{},
|
||||
remeberedPath: []string{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +42,24 @@ func NewApp() *App {
|
||||
// so we can call the runtime methods
|
||||
func (a *App) startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
|
||||
remeberPath, err := GetRemeberPath()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, err := os.Stat(remeberPath); err != nil {
|
||||
return
|
||||
}
|
||||
data, err := ioutil.ReadFile(remeberPath)
|
||||
|
||||
base := strings.Split(string(data), "\n")
|
||||
a.remeberedPath = []string{}
|
||||
|
||||
for _, elm := range base {
|
||||
if elm != "" {
|
||||
a.remeberedPath = append(a.remeberedPath, elm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) Close() {
|
||||
@ -81,6 +113,37 @@ func (a *App) SearchMathEql(value string) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) SearchRemeberDir(value string) []string {
|
||||
if value == "" {
|
||||
if len(a.remeberedPath) >= 5 {
|
||||
return a.remeberedPath[0:6]
|
||||
}
|
||||
return a.remeberedPath
|
||||
}
|
||||
|
||||
reg, err := regexp.Compile(value)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
if len(a.remeberedPath) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
n_list := []string{}
|
||||
|
||||
for _, elm := range a.remeberedPath {
|
||||
if reg.MatchString(elm) {
|
||||
n_list = append(n_list, elm)
|
||||
}
|
||||
if len(n_list) >= 5 {
|
||||
return n_list
|
||||
}
|
||||
}
|
||||
|
||||
return n_list
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (a *App) Search(value string) []string {
|
||||
if len(a.inputList) == 0 {
|
||||
@ -122,3 +185,8 @@ func (a *App) Enter(value string) {
|
||||
fmt.Printf("%s", value)
|
||||
runtime.Quit(a.ctx)
|
||||
}
|
||||
|
||||
func (a *App) EnterDir(value string) {
|
||||
fmt.Printf("ghostty --working-directory=%s", value)
|
||||
runtime.Quit(a.ctx)
|
||||
}
|
||||
|
@ -1,171 +1,206 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
SearchMath,
|
||||
Close,
|
||||
SearchMathEql,
|
||||
SearchDict,
|
||||
Search,
|
||||
Enter,
|
||||
} from "../wailsjs/go/main/App.js";
|
||||
import {
|
||||
SearchMath,
|
||||
Close,
|
||||
SearchMathEql,
|
||||
SearchDict,
|
||||
Search,
|
||||
Enter,
|
||||
EnterDir,
|
||||
SearchRemeberDir,
|
||||
} from "../wailsjs/go/main/App.js";
|
||||
|
||||
let searchText: string;
|
||||
let searchText: string;
|
||||
|
||||
let mathRes: string | null;
|
||||
let eqRes: string | null;
|
||||
let dictRes: string | null;
|
||||
let search: string[] | null;
|
||||
let selectedI: number = 0;
|
||||
let mathRes: string | null;
|
||||
let eqRes: string | null;
|
||||
let dictRes: string | null;
|
||||
let search: string[] | null;
|
||||
let remeberSearch: string[] = [];
|
||||
let selectedI: number = 0;
|
||||
|
||||
let searchBar: HTMLInputElement;
|
||||
let searchBar: HTMLInputElement;
|
||||
|
||||
$: searchBar?.focus();
|
||||
$: searchBar?.focus();
|
||||
|
||||
function findRes(searchText: string) {
|
||||
Search(searchText).then((res: string[] | null) => {
|
||||
search = res;
|
||||
if (search && search.length < selectedI) {
|
||||
selectedI = 0;
|
||||
}
|
||||
});
|
||||
if (!searchText) {
|
||||
mathRes = null;
|
||||
eqRes = null;
|
||||
dictRes = null;
|
||||
return;
|
||||
}
|
||||
SearchMath(searchText).then((res: string | null) => {
|
||||
mathRes = res;
|
||||
});
|
||||
SearchMathEql(searchText).then((res: string | null) => {
|
||||
eqRes = res;
|
||||
});
|
||||
SearchDict(searchText).then((res: string | null) => {
|
||||
dictRes = res;
|
||||
});
|
||||
}
|
||||
function findRes(searchText: string) {
|
||||
Search(searchText).then((res: string[] | null) => {
|
||||
search = res;
|
||||
if (search && search.length < selectedI) {
|
||||
selectedI = 0;
|
||||
}
|
||||
});
|
||||
SearchRemeberDir(searchText).then((res: string[] | null) => {
|
||||
console.log("here", res);
|
||||
remeberSearch = res ?? [];
|
||||
});
|
||||
if (!searchText) {
|
||||
mathRes = null;
|
||||
eqRes = null;
|
||||
dictRes = null;
|
||||
return;
|
||||
}
|
||||
SearchMath(searchText).then((res: string | null) => {
|
||||
mathRes = res;
|
||||
});
|
||||
SearchMathEql(searchText).then((res: string | null) => {
|
||||
eqRes = res;
|
||||
});
|
||||
SearchDict(searchText).then((res: string | null) => {
|
||||
dictRes = res;
|
||||
});
|
||||
}
|
||||
|
||||
$: findRes(searchText);
|
||||
$: findRes(searchText);
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="main">
|
||||
<input
|
||||
class="main-search"
|
||||
bind:this={searchBar}
|
||||
bind:value={searchText}
|
||||
placeholder="Search"
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
Close();
|
||||
} else if (e.key === "ArrowDown") {
|
||||
selectedI = Math.min(selectedI + 1, (search ?? []).length);
|
||||
} else if (e.key === "ArrowUp") {
|
||||
selectedI = Math.max(selectedI - 1, 0);
|
||||
} else if (e.key === "Enter") {
|
||||
if (search[selectedI]) {
|
||||
Enter(search[selectedI]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div style="padding: 0 10px">
|
||||
{#if searchText?.match(/^#[\da-f]{3}([\da-f]{3})?$/)}
|
||||
<div style="display: flex; gap: 20px; align-items: center; padding: 20px;">
|
||||
<h1>Color</h1>
|
||||
<div class="color-block" style="--background-color: {searchText};"></div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if mathRes}
|
||||
<div>
|
||||
<h1>Calculations</h1>
|
||||
<div class="math-res">
|
||||
<b>></b>
|
||||
{mathRes}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if eqRes}
|
||||
<div>
|
||||
<h1>Equasion</h1>
|
||||
<div class="math-res">
|
||||
<b>></b>
|
||||
{eqRes.substring(0, eqRes.length - 2)}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if dictRes}
|
||||
{@const data = JSON.parse(dictRes)[0]}
|
||||
<div>
|
||||
<h1>Dictionary ({data.word})</h1>
|
||||
<div
|
||||
style="color: white; max-height: {!search ||
|
||||
search.length === 0
|
||||
? '70vh'
|
||||
: '20vh'}; overflow-y: auto;"
|
||||
>
|
||||
{@html data.definition}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if search}
|
||||
<div style="overflow: auto; max-height: 600px;">
|
||||
{#each search as item, i}
|
||||
<div
|
||||
style="color: white; font-size: 18px; padding: 10px 5px; background: {selectedI ===
|
||||
i
|
||||
? 'oklch(71.4% 0.203 305.504 / 20)'
|
||||
: ''}"
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<input
|
||||
class="main-search"
|
||||
bind:this={searchBar}
|
||||
bind:value={searchText}
|
||||
placeholder="Search"
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
Close();
|
||||
} else if (e.key === "ArrowDown") {
|
||||
selectedI = Math.min(
|
||||
selectedI + 1,
|
||||
(search ?? []).length + (remeberSearch ?? []).length,
|
||||
);
|
||||
} else if (e.key === "ArrowUp") {
|
||||
selectedI = Math.max(selectedI - 1, 0);
|
||||
} else if (e.key === "Enter") {
|
||||
if (selectedI < remeberSearch.length) {
|
||||
EnterDir(remeberSearch[selectedI]);
|
||||
return;
|
||||
}
|
||||
if (search[selectedI - remeberSearch.length]) {
|
||||
Enter(search[selectedI - remeberSearch.length]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div style="padding: 0 10px">
|
||||
{#if remeberSearch.length > 0}
|
||||
<div
|
||||
style="overflow: auto; max-height: 600px; border-bottom: 1px #fff solid; margin-bottom: 10px;"
|
||||
>
|
||||
<h1>Remebered Paths</h1>
|
||||
{#each remeberSearch as item, i}
|
||||
<div
|
||||
style="color: white; font-size: 18px; padding: 10px 5px; background: {selectedI ===
|
||||
i
|
||||
? 'oklch(71.4% 0.203 305.504 / 20)'
|
||||
: ''}"
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if searchText?.match(/^#[\da-f]{3}([\da-f]{3})?$/)}
|
||||
<div
|
||||
style="display: flex; gap: 20px; align-items: center; padding: 20px;"
|
||||
>
|
||||
<h1>Color</h1>
|
||||
<div
|
||||
class="color-block"
|
||||
style="--background-color: {searchText};"
|
||||
></div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if mathRes}
|
||||
<div>
|
||||
<h1>Calculations</h1>
|
||||
<div class="math-res">
|
||||
<b>></b>
|
||||
{mathRes}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if eqRes}
|
||||
<div>
|
||||
<h1>Equasion</h1>
|
||||
<div class="math-res">
|
||||
<b>></b>
|
||||
{eqRes.substring(0, eqRes.length - 2)}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if dictRes}
|
||||
{@const data = JSON.parse(dictRes)[0]}
|
||||
<div style="margin-bottom: 10px; border-bottom: 1px #fff solid;">
|
||||
<h1>Dictionary ({data.word})</h1>
|
||||
<div
|
||||
style="color: white; max-height: {!search || search.length === 0
|
||||
? '70vh'
|
||||
: '20vh'}; overflow-y: auto;"
|
||||
>
|
||||
{@html data.definition}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if search}
|
||||
<div style="overflow: auto; max-height: 600px;">
|
||||
{#each search as item, i}
|
||||
<div
|
||||
style="color: white; font-size: 18px; padding: 10px 5px; background: {selectedI ===
|
||||
i + (remeberSearch ?? []).length
|
||||
? 'oklch(71.4% 0.203 305.504 / 20)'
|
||||
: ''}"
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
:global(html) {
|
||||
overflow: hidden;
|
||||
}
|
||||
main {
|
||||
height: 600px;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
:global(html) {
|
||||
overflow: hidden;
|
||||
}
|
||||
main {
|
||||
height: 600px;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main {
|
||||
background: #181818;
|
||||
border-radius: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
.main {
|
||||
background: #181818;
|
||||
border-radius: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
padding: 10px 0 5px 0;
|
||||
margin: 0;
|
||||
}
|
||||
h1 {
|
||||
color: white;
|
||||
padding: 10px 0 5px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.math-res {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
.math-res {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.main-search {
|
||||
background: #181818;
|
||||
height: 20px;
|
||||
width: 98%;
|
||||
padding: 5px;
|
||||
font-size: 20px;
|
||||
outline: none;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
border: #151515 solid 2px;
|
||||
}
|
||||
.color-block {
|
||||
background: var(--background-color);
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
.main-search {
|
||||
background: #181818;
|
||||
height: 20px;
|
||||
width: 98%;
|
||||
padding: 5px;
|
||||
font-size: 20px;
|
||||
outline: none;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
border: #151515 solid 2px;
|
||||
}
|
||||
.color-block {
|
||||
background: var(--background-color);
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
</style>
|
||||
|
4
frontend/wailsjs/go/main/App.d.ts
vendored
4
frontend/wailsjs/go/main/App.d.ts
vendored
@ -5,6 +5,8 @@ export function Close():Promise<void>;
|
||||
|
||||
export function Enter(arg1:string):Promise<void>;
|
||||
|
||||
export function EnterDir(arg1:string):Promise<void>;
|
||||
|
||||
export function Search(arg1:string):Promise<Array<string>>;
|
||||
|
||||
export function SearchDict(arg1:string):Promise<any>;
|
||||
@ -12,3 +14,5 @@ export function SearchDict(arg1:string):Promise<any>;
|
||||
export function SearchMath(arg1:string):Promise<any>;
|
||||
|
||||
export function SearchMathEql(arg1:string):Promise<any>;
|
||||
|
||||
export function SearchRemeberDir(arg1:string):Promise<Array<string>>;
|
||||
|
@ -10,6 +10,10 @@ export function Enter(arg1) {
|
||||
return window['go']['main']['App']['Enter'](arg1);
|
||||
}
|
||||
|
||||
export function EnterDir(arg1) {
|
||||
return window['go']['main']['App']['EnterDir'](arg1);
|
||||
}
|
||||
|
||||
export function Search(arg1) {
|
||||
return window['go']['main']['App']['Search'](arg1);
|
||||
}
|
||||
@ -25,3 +29,7 @@ export function SearchMath(arg1) {
|
||||
export function SearchMathEql(arg1) {
|
||||
return window['go']['main']['App']['SearchMathEql'](arg1);
|
||||
}
|
||||
|
||||
export function SearchRemeberDir(arg1) {
|
||||
return window['go']['main']['App']['SearchRemeberDir'](arg1);
|
||||
}
|
||||
|
82
main.go
82
main.go
@ -2,6 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
@ -13,6 +18,83 @@ import (
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 {
|
||||
if os.Args[1] == "--remeber" {
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal("Could not get working directory", err)
|
||||
return
|
||||
}
|
||||
|
||||
remeber_path, err := GetRemeberPath()
|
||||
if err != nil {
|
||||
log.Fatal("Could not create/open the remeber file")
|
||||
return
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(remeber_path)
|
||||
if err != nil {
|
||||
log.Fatal("Could not read the remeber file")
|
||||
return
|
||||
}
|
||||
if strings.Contains(fmt.Sprintf("%s\n", path), string(data)) {
|
||||
log.Fatal("This path is already remebered")
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(remeber_path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
log.Fatal("Could not create/open the remeber file")
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err = f.WriteString(fmt.Sprintf("%s\n", path)); err != nil {
|
||||
log.Fatal("Could not remeber", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Remebered: %s\n", path)
|
||||
} else if os.Args[1] == "--forget" {
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal("Could not get working directory", err)
|
||||
return
|
||||
}
|
||||
|
||||
remeber_path, err := GetRemeberPath()
|
||||
if err != nil {
|
||||
log.Fatal("Could not create/open the remeber file")
|
||||
return
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(remeber_path)
|
||||
if err != nil {
|
||||
log.Fatal("Could not read the remeber file")
|
||||
return
|
||||
}
|
||||
if !strings.Contains(fmt.Sprintf("%s\n", path), string(data)) {
|
||||
fmt.Printf("Forgotten*: %s\n", path)
|
||||
return
|
||||
}
|
||||
|
||||
base := strings.Split(string(data), "\n")
|
||||
n_list := []string{}
|
||||
for _, elm := range base {
|
||||
if elm != path {
|
||||
n_list = append(n_list, elm)
|
||||
}
|
||||
}
|
||||
|
||||
os.WriteFile(remeber_path, []byte(strings.Join(n_list, "\n")), 0666)
|
||||
|
||||
fmt.Printf("Forgotten: %s\n", path)
|
||||
} else {
|
||||
log.Fatal("Unkown option")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Create an instance of the app structure
|
||||
app := NewApp()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user