feat: add regex option for search bangs

pull/899/head
NecRaul 2025-12-08 00:34:45 +07:00
parent 784bf53425
commit 856f91b03d
No known key found for this signature in database
4 changed files with 51 additions and 6 deletions

@ -1264,11 +1264,12 @@ What now? [Bangs](https://duckduckgo.com/bangs). They're shortcuts that allow yo
![](images/search-widget-bangs-preview.png)
##### Properties for each bang
| Name | Type | Required |
| ---- | ---- | -------- |
| title | string | no |
| shortcut | string | yes |
| url | string | yes |
| Name | Type | Required | Default |
| ---- | ---- | -------- | ------- |
| title | string | no | |
| shortcut | string | yes | |
| url | string | yes | |
| regex | string | no | |
###### `title`
Optional title that will appear on the right side of the search bar when the query starts with the associated shortcut.
@ -1292,6 +1293,41 @@ url: https://store.steampowered.com/search/?term={QUERY}
url: https://www.amazon.com/s?k={QUERY}
```
###### `regex`
Optional regular expression that extracts multiple values from the query. If provided, the regex is applied to the query after removing the bang shortcut.
Example:
```yaml
- title: Google Translate
shortcut: "!tl"
regex: "^(\\w+):(\\w+)\\s+(.+)$"
url: "https://translate.google.com/?sl={QUERY}&tl={QUERY}&text={QUERY}&op=translate"
```
Typing
```
!tl en:fr hello world
```
would result in final URL being
```
https://translate.google.com/?sl=en&tl=fr&text=hello%20world&op=translate
```
and
```
!tl auto:en bonjour le monde
```
would result in final URL being
```
https://translate.google.com/?sl=auto&tl=en&text=bonjour%20le%20monde&op=translate
```
### Group
Group multiple widgets into one using tabs. Widgets are defined using a `widgets` property exactly as you would on a page column. The only limitation is that you cannot place a group widget or a split column widget within a group widget.

@ -134,6 +134,14 @@ function setupSearchBoxes() {
if (currentBang != null) {
query = input.slice(currentBang.dataset.shortcut.length + 1);
searchUrlTemplate = currentBang.dataset.url;
const regexString = currentBang.dataset.regex;
const match = regexString && query.match(new RegExp(regexString));
if (match) {
query = match.at(-1);
match.slice(1, -1).forEach((m) => {
searchUrlTemplate = searchUrlTemplate.replace("!QUERY!", encodeURIComponent(m));
});
}
} else {
query = input;
searchUrlTemplate = defaultSearchUrl;

@ -6,7 +6,7 @@
<div class="search widget-content-frame padding-inline-widget flex gap-15 items-center" data-default-search-url="{{ .SearchEngine }}" data-new-tab="{{ .NewTab }}" data-target="{{ .Target }}">
<div class="search-bangs">
{{ range .Bangs }}
<input type="hidden" data-shortcut="{{ .Shortcut }}" data-title="{{ .Title }}" data-url="{{ .URL }}">
<input type="hidden" data-shortcut="{{ .Shortcut }}" data-title="{{ .Title }}" data-url="{{ .URL }}" data-regex="{{ .Regex }}">
{{ end }}
</div>

@ -12,6 +12,7 @@ type SearchBang struct {
Title string
Shortcut string
URL string
Regex string
}
type searchWidget struct {