Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Support for plugins #96

Open
czhang03 opened this issue Jan 21, 2019 · 24 comments
Open

[Feature Request] Support for plugins #96

czhang03 opened this issue Jan 21, 2019 · 24 comments

Comments

@czhang03
Copy link

For both wox and alferd, plug-ins are a essential part of the app and improves usability by a great deal.

Please support developing plug-ins.

@czhang03
Copy link
Author

czhang03 commented Jan 22, 2019

Here is some documentation on how wox handles plugins:

http://doc.wox.one/en/plugin/create_plugin.html
http://doc.wox.one/en/plugin/plugin_json.html


Basically, in each plugin there is a plugin.json specifies all the basic metadata including version, name, etc. There are two things worth noting:

  1. UUID: I don't know whether this is necessary, many modern package managers no longer use UUID as id. For example, npm and choco.
  2. Executable file: This is the file specifying the executable, for example the python file or the compiled executable. In our case I think we can support typescript and javascript plugin first and then explore the possibility of supporting other type of plugins (python plugin or executable plugin).

wox gains all its functionality from plugins. I think this is a really robust and useful idea.

This idea gives user full control of the functionality they want (if they don't want certain functionality, they can just disable or uninstall that plugin), and makes the code much more modularized and extendable.

If we build the plugin system, then all the searcher and builder can be isolated and become plugins. also operating-system-settings and programs-plugin will be in their respective plugin folder. Results in a much cleaner src folder.

@czhang03
Copy link
Author

czhang03 commented Jan 22, 2019

Some functionality to keep in mind while developing plugins:

  1. Plugins should be able to install external packages if they want. For example when developing a calendar plugin, a library to generate ics file will be really helpful. Therefore, we need to handle installing dependency when installing and updating a plugin.
  2. We cannot simply invoke a command to the main file, because in a plugin, there might be other helper files and dependency. We need to find an elegant way to load in the plugin and then invoke the query and contextMenu function.
  3. Relevance of results. When two plugin have the same activation keyword, we need to sort these results by relevance of these results. This is very hard.
  4. Language options. The ueli should send in a config input or a config global constant to the plugin to tell them about some user options, including languages. There is also privacy concerns, user should be able to control what will sent into the plugin.

@alanaasmaa
Copy link

Ueli looks like currently best launcher i have found. But it really needs simple way to create own plugins and features. Currently hain seems to be best option for me, but for some reason I like ueli more.

Maybe I can somehow help with plugins?

@oliverschwendener
Copy link
Owner

In my opinion implementing a plugin manager is too overkill for now and will complicate stuff too much. If someone wants to implement a new plugin/feature it can be integrated directly to the app by making a pull request. Closing this for now until I really see the need for plugin system or someone else wants to implement this.

@NickSeagull
Copy link

Hey @oliverschwendener, +1 to this. My biggest uses of Alfred on Mac were:

  • Quick search of AWS dashboards
  • Quick search of GitHub repos
  • Manage Spotify within the launcher
  • Fast switch to a Slack channel
  • Switch between open windows

I think that these features should not be a main part of Ueli, because they are not something that everyone will want to use.

I drafted a possible implementation of a plugin manager, and it could be quite simple in practice. Instead of going with all the full pledged package repo, UI for the packages, etc... We can start with a configuration file where the user can specify github repos for the plugins in the format user/repo.

Ueli would then clone/download the repo and dynamically require the main module on load.

When that module is loaded, it would add itself to the list of built-in plugins. What do you think?

@oliverschwendener
Copy link
Owner

Ok I totally see the need for a plugin system now. People start to have needs for special usecases and this is where custom plugins come in. It would be really cool if there would be a easy way to develop plugins for ueli and install them. I just have no clue how to implement this. I just really want to avoid compatibility problems when adding updates/changes to the "core" of ueli.

I guess I have to look into this in the nearer future. Maybe this is something for v9.0.0. I'll reopen this issue.

Thanks for the input @NickSeagull

@oliverschwendener oliverschwendener added this to the Version 9.0.0 milestone Dec 2, 2019
@NickSeagull
Copy link

I think that the first step is already well setup, which is setting up an interface, and there is already one called ExecutionPlugin.

The next step would be how to indicate Ueli to load the plugin. The approach that Wox takes is to make all plugins have a class named Main, in order to know how to load them.

We could create an @*Plugin decorator that loads the class of the plugin perhaps?

I'm thinking that making each plugin a separate repo/project makes sense, so it looks like so:

plugin-repo
|- index.ts
|- package.json
|- ... more stuff

The contents of index.ts would be:

@ExecutionPlugin
export class CalculatorPlugin {    // no need for `extends` here, as the decorator can enforce it
  ...
}

in the package.json a main file is specified. so we can make Ueli aware of which file it would load.


Regarding distribution, I'd start with a .ueli.yaml file in $HOME and inside, some contents that look like:

plugins:
  - oliverschwendener/ueli-calculator-plugin@master

When Ueli starts, it would:

  1. Check that file for the plugins
  2. Download the zip from the tag in GitHub
  3. Extract it into the folder where Ueli stores its assets, perhaps to plugins/ueli-calculator-plugin
  4. Run npm run pack (or build, or compile, whatever command to generate the main file)
  5. Check the package.json inside of that folder for knowing where the main file is located
  6. require that main file
  7. The decorator then executes the needed code, where it pushes the class into the appropriate list at search-engine.ts

How does that sound?

@s-kerdel
Copy link

What is the progress on this feature? Are there any updates since December 2019?

@danielsteiner
Copy link

I have just started working on this at my fork. I will also provide a sample plugin repository that can be used for this purpose.

@tonyke-bot
Copy link

Gentle ping on this thread. @oliverschwendener What's our progress here? I'm eager to write some custom plugin for ueli so really want to see the plugin system getting landed.

If you are designing a plugin system, what about putting your idea/specification into the Discussion and together the community finalize the design?

@scorgn
Copy link

scorgn commented Feb 1, 2021

I wanted to create a custom plugin to play music on Spotify from Ueli. I didn't see any way to do this, so I made a workaround. The workaround might be a little bit over the top just to play music on Spotify, but I use it all the time. It could be used for other things as well.

To achieve this I had to create a couple different things.

First, I created a web application to act as a "Search Engine". I used Laravel but there are definitely better tools for this than Laravel/PHP. This search engine would search Spotify API for results for the query and return the results. However, before returning the results, it saves all the results with their URI's. It hashes the names of the result to use as the key. For example, if one of the results is "Yellow Submarine by The Beatles", it would md5 hash that string and cache the Spotify URI using the md5 hash as the key.

The second thing I had to create was a "Browser" application that handled custom URIs. In this instance the URI is spotify-search:. I used Platypus to turn an sh script into a MacOS application, and register it as the custom URI handler for spotify-search:. I also set it to run in the background.

To hook it up with Ueli I added a "New websearch engine" to Ueli. For the "Suggestion URL" I used the search engine I created, so I entered http://spotify-search-engine.test/api/suggestions/{{query}}. For the URL I used the custom URI mentioned before. So I entered spotify-search:{{query}} The prefix I used is s?.

This means that when you select a result in Ueli, it actually runs the sh script in the background and passes it the query string.

The sh script makes a request to the same Laravel application used before with the query string. The Laravel application will md5 hash it and check the cache to find the URI that was cached earlier, then returns it. The sh script will use osascript to play the Spotify URI in the background.

So in all, the flow goes...

  • Ueli uses Laravel Application to get suggestions for a query
  • Laravel application gets suggestions from Spotify API
  • Laravel application caches all suggestions along with their URI and returns search suggestions
  • User selects a search suggestion, which uses a custom URI scheme to open the "Browser application" (sh script) in the background
  • The "Browser" application makes an API request to the Laravel Application with the search query in order to get the URI that was saved
  • The "Browser" application uses osascript to tell Spotify to play that URI.

It's a pretty complex workaround just to play music on Spotify but it works pretty well. I'm considering hosting the Laravel application publicly, then letting people download the "Browser application" (sh script) so they can set up their Ueli to be able to play Spotify as well.

I'm sure it would work well for other scenarios as well. I'd be happy to help someone build out a similar solution if they want to make it work for a different scenario.

@WatchTheory
Copy link

I found this and would like to see some like this in ueli.
https://github.com/spotlightify/spotlightify

@freedsny
Copy link

freedsny commented Apr 5, 2021

Ueli parece el mejor lanzador que he encontrado actualmente. Pero realmente necesita una manera sencilla de crear sus propios plugins y características. Actualmente hain parece ser la mejor opción para mí, pero por alguna razón me gusta ueli más.

Tal vez de alguna manera puedo ayudar con plugins?

Que tal esta app: https://www.fluentsearch.net/
https://install.appcenter.ms/users/adirh3-gmail.com/apps/fluent-search/distribution_groups/daily

@freedsny
Copy link

freedsny commented Apr 6, 2021

Ok I totally see the need for a plugin system now. People start to have needs for special usecases and this is where custom plugins come in. It would be really cool if there would be a easy way to develop plugins for ueli and install them. I just have no clue how to implement this. I just really want to avoid compatibility problems when adding updates/changes to the "core" of ueli.

I guess I have to look into this in the nearer future. Maybe this is something for v9.0.0. I'll reopen this issue.

Thanks for the input @NickSeagull

Please don't forget the Spanish Language, For the plugin, and the dictionary, and others

@freedsny
Copy link

freedsny commented Apr 6, 2021

Please don't forget the Spanish Language, For the plugin, and the dictionary, and others

@freedsny
Copy link

freedsny commented Apr 6, 2021

Please friends, put plugin from the dictionary but a dictionary is Spanish language, because the one you have is in English

@NickSeagull
Copy link

NickSeagull commented Apr 8, 2021

@freedsny even though I do speak spanish and understand your needs, I think that you're confused with this issue, we are discussing allowing Ueli to support plugins, as right now it doesn't.

As I understand you're requesting a specific plugin, which is impossible right now because Ueli doesn't support plugins. Regarding your request for the spanish language I suggest you to create a new issue

@freedsny
Copy link

freedsny commented Apr 8, 2021 via email

@tomaskall
Copy link

I found this and would like to see some like this in ueli. https://github.com/spotlightify/spotlightify

Did you get any soloution for this? Have any good tips of navigating spotify via keyboard?

@tomaskall
Copy link

Did you get any soloution for this? Have any good tips of navigating spotify via keyboard?

I wanted to create a custom plugin to play music on Spotify from Ueli. I didn't see any way to do this, so I made a workaround. The workaround might be a little bit over the top just to play music on Spotify, but I use it all the time. It could be used for other things as well.

To achieve this I had to create a couple different things.

First, I created a web application to act as a "Search Engine". I used Laravel but there are definitely better tools for this than Laravel/PHP. This search engine would search Spotify API for results for the query and return the results. However, before returning the results, it saves all the results with their URI's. It hashes the names of the result to use as the key. For example, if one of the results is "Yellow Submarine by The Beatles", it would md5 hash that string and cache the Spotify URI using the md5 hash as the key.

The second thing I had to create was a "Browser" application that handled custom URIs. In this instance the URI is spotify-search:. I used Platypus to turn an sh script into a MacOS application, and register it as the custom URI handler for spotify-search:. I also set it to run in the background.

To hook it up with Ueli I added a "New websearch engine" to Ueli. For the "Suggestion URL" I used the search engine I created, so I entered http://spotify-search-engine.test/api/suggestions/{{query}}. For the URL I used the custom URI mentioned before. So I entered spotify-search:{{query}} The prefix I used is s?.

This means that when you select a result in Ueli, it actually runs the sh script in the background and passes it the query string.

The sh script makes a request to the same Laravel application used before with the query string. The Laravel application will md5 hash it and check the cache to find the URI that was cached earlier, then returns it. The sh script will use osascript to play the Spotify URI in the background.

So in all, the flow goes...

  • Ueli uses Laravel Application to get suggestions for a query
  • Laravel application gets suggestions from Spotify API
  • Laravel application caches all suggestions along with their URI and returns search suggestions
  • User selects a search suggestion, which uses a custom URI scheme to open the "Browser application" (sh script) in the background
  • The "Browser" application makes an API request to the Laravel Application with the search query in order to get the URI that was saved
  • The "Browser" application uses osascript to tell Spotify to play that URI.

It's a pretty complex workaround just to play music on Spotify but it works pretty well. I'm considering hosting the Laravel application publicly, then letting people download the "Browser application" (sh script) so they can set up their Ueli to be able to play Spotify as well.

I'm sure it would work well for other scenarios as well. I'd be happy to help someone build out a similar solution if they want to make it work for a different scenario.

Have any good tips of navigating spotify via keyboard?

@scorgn
Copy link

scorgn commented Aug 22, 2022

Have any good tips of navigating spotify via keyboard?

Are you asking outside of the context of ueli, just how to make keyboard shortcuts for spotify?

@tomaskall
Copy link

Have any good tips of navigating spotify via keyboard?

Are you asking outside of the context of ueli, just how to make keyboard shortcuts for spotify?

I really love UELI, so my wet dream would be a solution within UELI.

My Usecase is, i wanna have the ability to start a number o playlists, type a few keys in the keylist name ang then hit enter and spotify starts my playlist, not need not navigate spotify with the mouse.

I can make a file for each playlist, i tried (https://cloakersmoker.github.io/Spotify.ahk/about.html) and made an .ahk file for each playlist, it works, but sometimes i get "device not connect", perhaps an API problem.

A solution wihtin in UELI or outside would be great. And i could pay money for it,

I have Spotify premium.

@ghz
Copy link

ghz commented Oct 31, 2022

+1 for plugin !
Coming from Wox software, there is a lot of missing features/plugins that could improve my workflow a lot.
I love UELI UI/UX and its core features but allowing other plugin could be a game changer for this app.

@tomm-m
Copy link

tomm-m commented Nov 12, 2022

Yeah, Ueli looks great but because of the lack of plugins support, I think I'll use Wox/Cerebro/Hain instead 😞

@oliverschwendener oliverschwendener changed the title Support for plugins [Feature Request] Support for plugins May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests