Alex M Posted August 21, 2018 Share Posted August 21, 2018 I've gotten kind of spoiled with the extended actions for some searches (e.g. App name > Tab > Open in Finder), so every time I paste a URL I kind of expect to be able to hit tab and choose which browser to use to open it. But I can't. Is there any built-in way to do this? I do use the clipboard integration as well so it'd be great if I can do it directly from the history view as well but that's not required. I looked into creating a workflow with the open URL action, but that doesn't seem to work with providing a full URL and it requires me to set to browser in the workflow which kind of defeats the purpose. Link to comment
vitor Posted August 22, 2018 Share Posted August 22, 2018 If you change browsers that often depending on URL, you might want to take a look at these third-party options: Link to comment
Alex M Posted August 22, 2018 Author Share Posted August 22, 2018 I actually used to use Choosy when I used to do this a lot more, but it's infrequent enough these days that the extra annoyance of using a separate tool outweighs the benefit. What I'd really love would be a way to register a URL as a "filetype" so that I can get the usual extra menu. i.e. if I type <space>filename.txt<tab> (assuming the file exists obviously), one of the options is "Open with...". What I really want is a way to have that same sort of menu for a URL. Link to comment
Andrew Posted August 23, 2018 Share Posted August 23, 2018 On 8/21/2018 at 9:45 PM, Alex M said: I looked into creating a workflow with the open URL action, but that doesn't seem to work with providing a full URL and it requires me to set to browser in the workflow which kind of defeats the purpose. There are a few things you can do in Alfred's workflows which help with this. Firstly, you could have two separate Open URL actions configured as appropriate, then use modifiers on the connections... e.g. return on the result will open the first Open URL object in the default browser, alt+return will open in the second Open URL object with a specified browser. A simple workflow could be: Keyword to take a URL as argument -> two Open URL actions, one with a modifier. Another option is to dynamically configure the Open URL object. This is a more advanced workflow technique, but allows for significant flexibility using the JSON utility: https://www.alfredapp.com/help/workflows/utilities/json/ It's probably best to take the simple approach first. Alex M 1 Link to comment
deanishe Posted August 23, 2018 Share Posted August 23, 2018 (edited) If you're pasting URLs into Alfred, here's a workflow that shows you a bunch of browsers when you paste a URL into Alfred. It uses the keyword "http", so when you paste a URL into Alfred, it shows you "Open in Safari", "Open in Chrome" ... options. The browsers are configured in the browsers.py file in the workflow: """Open a URL in different browsers.""" from __future__ import print_function, absolute_import from collections import namedtuple import json import sys Browser = namedtuple('Browser', 'name path') BROWSERS = [ Browser(u'Safari', u'/Applications/Safari.app'), Browser(u'Chrome', u'/Applications/Google Chrome.app'), Browser(u'Firefox', u'/Applications/FirefoxDeveloperEdition.app'), ] def log(s, *args): """Simple STDERR logger.""" if args: s = s % args print(s, file=sys.stderr) def main(): """Run Script Filter.""" url = sys.argv[1].decode('utf-8') log('url=%r', url) items = [] for b in BROWSERS: items.append(dict( title='Open in ' + b.name, subtitle=b.path, arg=url, icon=dict( path=b.path, type='fileicon', ), valid=True, variables=dict( browser=b.path, url=url, ), )) json.dump(dict(items=items), sys.stdout) if __name__ == '__main__': main() Edited August 27, 2018 by deanishe vitor and Alex M 2 Link to comment
Alex M Posted August 23, 2018 Author Share Posted August 23, 2018 Thanks to everyone for the suggestions! I'm going to try an updated workflow this afternoon and I'll let you know how it works out. Thanks! Link to comment
Alex M Posted August 24, 2018 Author Share Posted August 24, 2018 I ended up doing a lot more work than I planned on this, but I'm pretty happy with what I came up with. I started with @deanishe's workflow and then edited the python script to get a list of URL handlers from the OS instead of requiring them to be hard-coded. This does slow down the workflow by about 500 ms which isn't ideal, but it gets the job done. I've also discovered Alfred-Workflow and the built in support for caching so I'm going to try that later in order to speed things up a bit. It'd be great if there was a way to pull URL handlers directly from Alfred/Spotlight, but all I've been able to find so far is calling 'lsregister -dump' which is where most of the speed hit comes from. If anyone has any suggestions on how to speed that bit up I'd greatly appreciate it. In the meantime, here's the updated code I used for the workflow: """Open a URL in different browsers""" from __future__ import print_function, absolute_import from collections import namedtuple import json import sys import os import re rexps = [ re.compile('^\s*(bundle)\s*id:\s*(\d*)'), re.compile('^\s*(path):\s*(.*)'), re.compile('^\s*(name):\s*(.*)'), re.compile('^\s*(bindings):\s*(.*)') ] def log(s, *args): """Simple STDERR logger.""" if args: s = s % args print(s, file=sys.stderr) def gethandlers(): handlers = {} bundle = "" dump = os.popen("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump") for line in dump.readlines(): for rexp in rexps: m = rexp.match(line) if not m: continue key = m.group(1) value = m.group(2) if key == "bundle": if bundle != value: bundle = value name = "" path = "" if key == "name" and not name: name = value if key == "path" and not path: path = value if key == "bindings" and 'http:' in value.split(","): handlers[name] = path dump.close() handlers.pop('nwjs', None) handlers.pop('VLC media player', None) return handlers def main(): """Run Script Filter.""" url = ("http" + sys.argv[1]).decode('utf-8') log('url=%r', url) items = [] browsers = gethandlers() for b in sorted(browsers): items.append(dict( title='Open in ' + b, subtitle=browsers[b], arg=url, icon=dict( path=browsers[b], type='fileicon', ), valid=True, variables=dict( browser=browsers[b], url=url, ), )) json.dump(dict(items=items), sys.stdout) if __name__ == '__main__': main() Link to comment
deanishe Posted August 24, 2018 Share Posted August 24, 2018 (edited) From one of my workflows, here's a script that retrieves all apps that can open a URL (scheme). You mostly need to change the URLs in lines 35 and 58 from mailto: to http: URLs. I wouldn't bother with it personally. So many apps can open http URLs that you'll probably end up adding a whitelist to keep the results clean anyway. Edited August 27, 2018 by deanishe Link to comment
Alex M Posted August 25, 2018 Author Share Posted August 25, 2018 Thanks for all of your help @deanishe, definitely appreciated. Here's the pretty much completed product in case anyone else finds it useful: alfred-browser-choice Link to comment
deanishe Posted August 27, 2018 Share Posted August 27, 2018 I've updated my script to check if the input is a real URL, as it was annoying me a bit when looking up HTTP stuff in Dash. """Open a URL in different browsers.""" from __future__ import print_function, absolute_import from collections import namedtuple import json import re import sys Browser = namedtuple('Browser', 'name path') BROWSERS = [ Browser(u'Safari', u'/Applications/Safari.app'), Browser(u'Chrome', u'/Applications/Google Chrome.app'), Browser(u'Firefox', u'/Applications/FirefoxDeveloperEdition.app'), ] def log(s, *args): """Simple STDERR logger.""" if args: s = s % args print(s, file=sys.stderr) def is_url(s): """Return ``True``if ``s`` is an http(s) URL.""" return re.match(r'https?://\S+', s, re.IGNORECASE) def main(): """Run Script Filter.""" query = sys.argv[1].decode('utf-8') log('query=%r', query) if not is_url(query): log('not a URL; exiting') return items = [] for b in BROWSERS: items.append(dict( title=u'Open in ' + b.name, subtitle=u'Open “%s” in %s' % (query, b.name), arg=query, icon=dict( path=b.path, type='fileicon', ), valid=True, variables=dict( browser=b.path, url=query, ), )) json.dump(dict(items=items), sys.stdout) if __name__ == '__main__': sys.exit(main()) Link to comment
Travis Schmeisser Posted March 16, 2022 Share Posted March 16, 2022 This workflow seems to have stopped working for me randomly. Is there a replacement for this anyone is aware of? My searches so far aren't turning anything up and I heavily rely on this daily. Link to comment
Chris Messina Posted March 16, 2022 Share Posted March 16, 2022 2 hours ago, Travis Schmeisser said: This workflow seems to have stopped working for me randomly It's not random if you updated to macOS 12.3, which removed python. Link to comment
vitor Posted March 16, 2022 Share Posted March 16, 2022 @Travis Schmeisser See the Updated Third-Party Python 2 Workflows GitHub page. It explains the situation, links to instructions on regaining access to Python 2 and includes a fixed version of this Workflow. Link to comment
Travis Schmeisser Posted March 18, 2022 Share Posted March 18, 2022 Thank you @vitor! And, yeah, guess that's the culprit @Chris Messina. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now