Search Engine Help

Sooooo… I’m by no means not technical (FWIW career sysadmin, personally running various homeserver things, etc) but lisp is entirely new to me and man configuring certain things has been a journey so far haha. So anyway I really don’t have much of anything at this point I was figuring out theming first but now I’m at the point where I am hitting a wall with configuration and in this case specifically search engines.

So I ran through the relevant github issue on it as well as some user configs but still can’t figure it out sadly. If someone could help me understand how/where to put a custom list, how to edit the current search config (ddg and wiki), and how to set my default search engine that would be great.

I have made it to the point in my journey where I have figured out how to get to slots, classes, etc but the only thing I was successfully able to set was my default new buffer url using the configure button. When I navigate to the various search slots I can’t get whatever I input after hitting configure to work and seeing the current ones (ddg and wiki) sadly hasn’t helped me configure them or figure out how to set the default.

Anyway I know that is a lot but I don’t really have anything to show because honestly I am just at a loss for where I should even be beginning. Any and all help is appreciated, I think understanding this will help me move forward on a lot of config related aspects. Thank you!

2 Likes

If it helps at all I want to remove the current defaults and just have a single search engine (my own) and don’t want anything fancy like auto complete or what have you. Just want mine and want it to be the only option.

You might try something like the following:

(define-configuration buffer
  ((search-engines (make-search-engine "my search engine shortcut" "https://myurl.com?search=~a" "fallbackurl.com"))))

Hopefully that helps :slight_smile:

As a sort of cross post from the related GitHub issue for future wanderers. Not able to add a new search engine · Issue #1554 · atlas-engineer/nyxt · GitHub below is a broader working example from @jmercouris in that issue.

(defvar *my-search-engines*
  (list
   '("google" "https://www.google.com/search?q=~a" "https://www.google.com/")
   '("quickdocs" "http://quickdocs.org/search?q=~a" "http://quickdocs.org/")
   '("wiki" "https://en.wikipedia.org/w/index.php?search=~a" "https://en.wikipedia.org/")
   '("define" "https://en.wiktionary.org/w/index.php?search=~a" "https://en.wiktionary.org/")
   '("python3" "https://docs.python.org/3/search.html?q=~a" "https://docs.python.org/3")
   '("doi" "https://dx.doi.org/~a" "https://dx.doi.org/")))

(define-configuration buffer
  ((search-engines (append (mapcar (lambda (engine) (apply 'make-search-engine engine))
                                   *my-search-engines*)
                           %slot-default%))))


I can confirm that both the above and the simpler example given to me here on the forum work great.

@jmercouris while the above does seem to work how do I turn mine into the default? I’m not opposed to keeping wiki and ddg on as engines but no matter what I’m doing now that I can add new ones ddg is still the default if I type something sans shortcut

For the sake of using the example I cross posted that you put in the github issue. How would I make say google in that list the default?

Still can’t quite figure out the default piece…

(defvar *my-search-engines*
  (list
   '("google" "https://www.google.com/search?q=~a" "https://www.google.com/")
   '("quickdocs" "http://quickdocs.org/search?q=~a" "http://quickdocs.org/")
   '("wiki" "https://en.wikipedia.org/w/index.php?search=~a" "https://en.wikipedia.org/")
   '("define" "https://en.wiktionary.org/w/index.php?search=~a" "https://en.wiktionary.org/")
   '("python3" "https://docs.python.org/3/search.html?q=~a" "https://docs.python.org/3")
   '("doi" "https://dx.doi.org/~a" "https://dx.doi.org/")))

(define-configuration buffer
  ((search-engines (append (mapcar (lambda (engine) (apply 'make-search-engine engine))
                                   *my-search-engines*)
                           %slot-default%))))

The above works great to add them and make a list. But trying something like

(define-configuration buffer
  ((default-search-engine (make-search-engine "my search engine shortcut" "https://myurl.com?search=~a" "fallbackurl.com"))))

In my init or my auto-config doesn’t do anything to change the default from ddg.

@jmercouris As an alternative, and perhaps just an addition anyway that seems useful to me, is there a way to assign a search shortcut with a keybinding?

I tried adding something like "M-x" 'set-url google to my keybinding override but (as I kind of expected) that didn’t work. I think it would be useful anyway to be able to instantly call up a search with a binding instead of typing the shortcut everytime but I don’t know if that is possible. It would solve my default problem too since then ddg can stay the default wherever that is living but I can just override the current keybindings I use to start a search anyway.

Hm, no way to currently do this, but you could make a command to do it, would you like me to provide an example?

Yes that would be great as I have no idea where to start, I’ve tried a few things already as mentioned above and they didn’t work.

So, here is a command that only searches:

(define-command-global search-only (&key (prefill-current-url-p t))
  "Set the URL for the current buffer, completing with history."
  (let ((actions (list (make-command buffer-load* (suggestion-values)
                         "Load first selected URL in current buffer and the rest in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (buffer-load (url (first suggestion-values))))
                       (make-command new-buffer-load (suggestion-values)
                         "Load URL(s) in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (make-buffer-focus :url (url (first suggestion-values)))))))
    (prompt
     :prompt "Search"
     :sources (list (make-instance 'user-new-url-or-search-source :actions actions)))))

Also, the ‘default’ search engine, is simply the last one in the search engine list. So, if you want to make a specific search engine the default, then you need to reorder the list. Hopefully that helps!

For the default piece that doesn’t seem to work. Here is my code (with some omitted due to wanting them private) in my init file. But ddg still comes up as default.

(defvar *my-search-engines*
  (list
   '("hns" "https://hns.to/~a" "https://hns.to/")   
   '("git" "https://github.com/search?q=~a" "https://github.com/")
   '("prtn" "https://mail.protonmail.com/u/0/all-mail#keyword=~a" "https://mail.protonmail.com/")
   '("wiki" "https://en.wikipedia.org/w/index.php?search=~a" "https://en.wikipedia.org/")
   '("ddg" "https://duckduckgo.com/?q=~a" "https://duckduckgo.com/")
   '("snyxt" "https://discourse.atlas.engineer/search?q=~a" "https://discourse.atlas.engineer")
   '("az" "https://amazon.com/s?k=~a" "https://amazon.com/")))

(define-configuration buffer
  ((search-engines (append (mapcar (lambda (engine) (apply 'make-search-engine engine))
                                   *my-search-engines*)
                           %slot-default%))))

So in the above case amazon “az” should be the default right?

Notice that you are appending to the slot default, if “az” was to be your default, then you would have to do this:

(define-configuration buffer
  ((search-engines (mapcar (lambda (engine) (apply 'make-search-engine engine))
                                   *my-search-engines*))))

Well that was way easier than I was making it, thank you.

As for the search only command you gave me earlier:

(define-command-global search-only (&key (prefill-current-url-p t))
  "Set the URL for the current buffer, completing with history."
  (let ((actions (list (make-command buffer-load* (suggestion-values)
                         "Load first selected URL in current buffer and the rest in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (buffer-load (url (first suggestion-values))))
                       (make-command new-buffer-load (suggestion-values)
                         "Load URL(s) in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (make-buffer-focus :url (url (first suggestion-values)))))))
    (prompt
     :prompt "Search"
     :sources (list (make-instance 'user-new-url-or-search-source :actions actions)))))

Am I being dumb or just missing something simple? What would I adjust there to set it to a specific engine? So for instance az is my default but I want the above command to start with ddg by default?

You would have to customize the new-url-or-search-source. You can see the class definition here:

(define-class new-url-or-search-source (prompter:source)
  ((prompter:name "New URL or search query")
   (prompter:filter-preprocessor
    (lambda (suggestions source input)
      (declare (ignorable suggestions source))
      (input->queries input)))
   (prompter:filter nil)
   (prompter:actions '(buffer-load)))
  (:export-class-name-p t)
  (:documentation "This prompter source tries to \"do the right thing\" to
generate a new URL query from user input.
- If the query is a URL, open it directly.
- If it's a file, prefix the query with 'file://'.
- If it's a search engine shortcut, include it in the suggestions.
- If it's none of the above, use the `default-search-engine'."))

unfortunately it is not written in a easily extensible way. @ambrevar do you have any ideas about how one might easily modify this? Some obvious idea I am missing?

@ambrevar @jmercouris As can be seen from my plethora of questions so far I am incredibly unfamilar with all of this. But I am somewhat surprised (as I seem to be able to do similar things elsewhere) that there isn’t an easy way to “autofill” (so to speak) a set of text in a command and then continue typing. So essentially having the search command you gave me earlier start with "ddg " in the prompt buffer and then I can continue typing whatever I want. In essence a simple “hack” to give it the desired effect.

I’m not completely sure of what you are asking.

For instance set-url prefills the input with the current URL. Is this the feature you are looking for?

If so, it’s easy, just invoke the prompt with :input "your-text-here".

I thought the user wanted a search of only a specific search engine as the default. Pierres idea of prefilling in a preferred search engine shortcut is a brilliant solution!

Haha! @ambrevar got what I was aiming for. @jmercouris I tried to clarify but I think I mixed too many things together so I ended up making it more confusing. Basically I want to assign keybindings to each engine to essentially jump right into a specific search engine.

Now the problem I am facing (since it does mostly work I’m just getting picky) is that when adding the :input to @jmercouris it does work exactly as expected except the input "ddg " is selected so I am unable to start typing for that search engine right away without first hitting my right arrow key to remove the highlight. Make sense?

(define-command-global search-only (&key (prefill-current-url-p t))
  "Set the URL for the current buffer, completing with history."
  (let ((actions (list (make-command buffer-load* (suggestion-values)
                         "Load first selected URL in current buffer and the rest in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (buffer-load (url (first suggestion-values))))
                       (make-command new-buffer-load (suggestion-values)
                         "Load URL(s) in new buffer(s)."
                         (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                         (make-buffer-focus :url (url (first suggestion-values)))))))
    (prompt
     :prompt "Search"
     :input "ddg "
     :sources (list (make-instance 'user-new-url-or-search-source :actions actions)))))

If it is something technical in that I can’t get past no worries. Just trying to make it smoother for myself.

If it helps visualize my goal it is that C-l sets the url for my buffer yeah? I like that for sure but want to do say “C-l d” to immediately trigger a ddg search or “C-l g” a github search and so on. Just seems like it could be really seamless that way.

Hm, I don’t think there is a way to not have it highlighted. I guess that is an assumption we baked into the prompt implementation. @ambrevar do you think this would be a good option to add?