Jump to content

JimmyTheSaint

Member
  • Posts

    46
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

JimmyTheSaint's Achievements

Member

Member (4/5)

3

Reputation

  1. Thanks for introducing me to that debugger. Here's the screenshot. I guess it's some kind of n00bish mistake on my part, but I don't see it.
  2. What's the principle that it depends on? The workflow fails for me on every file I try in Path Finder, and I've tried mp3, text, doc, and pdf files. I select the Send via AirDrop workflow from the file actions, and nothing happens at all.
  3. In workflows, the hotkey feature requires hotkeys to use special characters (ctrl, opt, shift, cmd). As a touch-typist, it's greatly preferable to keep your fingers on the home row, and special characters require moving your hands away, slowing operating my keyboard down. I would like to be able to use simultaneous key presses to launch workflows. For example, simultaneously press the 'g' and 'n' keys to launch a bookmark to Google News. Because the key presses have to be simultaneous, the 'g' and 'n' keys would continue to function normally for typing text. The addition of non-special character 2-key chords would enable a lot of hotkey combos to sit comfortably under your fingers while your hands remain in the home position. I currently use Karabiner-Elements to map two-key chords to workflow external triggers, but if I could do these chords entirely within Alfred, I could streamline my computer configuration. From my experience with Karabiner, I've found that 3-chords and greater are less ergonomic, but that I type 2-key chords with 100% accuracy. I set up my most frequently used chords so that they're compact enough to actuate one-handed. I can then make the computer do stuff from arm's length, without actually sitting down at it.
  4. Thanks for this. It works for me when selecting files in Finder, but I user Path Finder as a Finder replacement, and it doesn't work with files selected in Path Finder. The Air Drop window simply never opens. Is there a fix?
  5. I did those two things, but there is no change, with the console listing the same sequence of messages. When I ran ffass, Alfred showed the message, "Registered. Re-open Firefox extension to connect." When I did the alternative method, I got this stuff posted in the terminal: Last login: Thu Jul 23 23:54:23 on console e@GRAY ~ % /Users/e/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0/alfred-firefox ; exit; panic: invalid Workflow environment: alfred_workflow_bundleid is not set, alfred_workflow_cache is not set, alfred_workflow_data is not set goroutine 1 [running]: github.com/deanishe/awgo.NewFromEnv(0x0, 0x0, 0xc0001260c0, 0x3, 0x3, 0xc0001260c0) /Users/daj/pkg/mod/github.com/deanishe/awgo@v0.22.1/workflow.go:159 +0xbe3 github.com/deanishe/awgo.New(0xc0001260c0, 0x3, 0x3, 0xc0001260a0) /Users/daj/pkg/mod/github.com/deanishe/awgo@v0.22.1/workflow.go:149 +0x47 main.init() /Users/daj/Code/Alfred/alfred-firefox-assistant/main.go:53 +0x360 [Process completed]
  6. I think it needs another update. I get this warning.
  7. Here's what was generated in the "Console" tab when I opened the extension: [popup] started popup.js:36:11 connected to popup alfred.js:118:13 received message Object { command: "status" } alfred.js:127:13 sent message Object { status: "disconnected" } alfred.js:123:13 [popup] status=disconnected popup.js:14:15 received message Object { command: "status" } alfred.js:127:13 sent message Object { status: "disconnected" } alfred.js:123:13 received message Object { command: "reconnect" } alfred.js:127:13 reconnecting to native app ... alfred.js:134:19 [popup] status=disconnected popup.js:14:15 native client connection failed: alfred.js:172:13 received message Object { command: "status" } alfred.js:127:13 sent message Object { status: "disconnected" } alfred.js:123:13 received message Object { command: "reconnect" } alfred.js:127:13 reconnecting to native app ... alfred.js:134:19 [popup] status=disconnected popup.js:14:15 native client connection failed:
  8. Also, I'm attaching a screenshot of the debugger in case you need me to access something else from it:
  9. I was only guessing that a "stack trace" was important. I had no idea the extension debugger was the important one because when I opened it, it seemed to show a lot less information than the log. Now I see if I click on the part on the left side that says "JS alfred.js" it shows a lot of info. I'm pasting that info here: /* global browser */ /** * Name of native application according to application manifest. * @var {string} appName */ const appName = 'net.deanishe.alfred.firefox'; const iconConnected = 'icons/bowler.svg'; const iconDisconnected = 'icons/bowler-red.svg'; /** * Tab object. * @param {tabs.Tab} tab - Native tab object to create Tab from. * @return {Object} - API Tab object. */ const Tab = tab => { let obj = {}; tab = tab || {}; obj.id = tab.id || 0; obj.windowId = tab.windowId || 0; obj.index = tab.index || 0; obj.title = tab.title || ''; obj.url = new URL(tab.url || ''); // obj.favicon = tab.favIconUrl || ''; obj.active = tab.active || false; obj.toString = function() { return `#${this.id} (${this.windowId}x${this.index}) "${this.title}" - ${this.url}`; }; return obj; }; /** * Bookmark object. * @param {bookmarks.BookmarkTreeNode} bm - Native object to create Bookmark from. * @return {Object} - API Bookmark object. */ const Bookmark = bm => { let obj = {}; bm = bm || {}; obj.id = bm.id || 0; obj.index = bm.index || 0; obj.title = bm.title || ''; obj.parentId = bm.parentId || 0; obj.type = bm.type || ''; obj.url = bm.url || ''; obj.toString = function() { return `#${this.id} "${this.title}" - ${this.url}`; }; return obj; }; /** * HistoryEntry object. * @param {history.HistoryItem} hi - Native object to create HistoryEntry from. * @return {Object} - API History object. */ const HistoryEntry = hi => { let obj = {}; hi = hi || {}; obj.id = hi.id || 0; obj.url = hi.url || ''; obj.title = hi.title || hi.url; obj.toString = function() { return `#${this.id} "${this.title}" - ${this.url}`; }; return obj; }; /** * Download object. * @param {downloads.DownloadItem} di - Native object to create Download from. * @return {Object} - API Download object. */ const Download = di => { let obj = {}; di = di || {}; obj.id = di.id || 0; obj.path = di.filename || ''; obj.size = di.fileSize || 0; obj.url = di.url || ''; obj.mime = di.mime || ''; obj.exists = di.exists || false; obj.error = di.error || ''; obj.toString = function() { return `#${this.id} "${this.path}" - ${this.url}`; }; return obj; }; /** * Extension application object. * @constructor */ const Background = function() { const self = this; self.port = null, self.nativePort = null, self.connected = false; self.onConnected = port => { self.port = port; port.onMessage.addListener(self.receive); console.debug('connected to popup'); }; self.send = msg => { self.port.postMessage(msg); console.debug('sent message', msg); }; self.receive = msg => { console.debug('received message', msg); if ('command' in msg) { switch (msg.command) { case 'status': self.send({ status: self.connected ? 'connected' : 'disconnected' }); return; case 'reconnect': console.debug('reconnecting to native app ...'); self.connectNative(); return; case 'reload': console.debug('reloading extension ...'); browser.runtime.reload(); return; } } }; self.connectNative = () => { self.connected = false; let listener = payload => { if (!self.connected) { self.connected = true; // self.nativePort.onDisconnect.removeListener(self.connectNativeFailed); self.onConnectedNative(); } self.receiveNative(payload); }; self.nativePort = browser.runtime.connectNative(appName); self.nativePort.onMessage.addListener(listener); self.nativePort.onDisconnect.addListener(self.connectNativeFailed); }; /** * Callback for connection failure. * Logs an error message to the console. */ self.connectNativeFailed = port => { let msg = ''; if (port.error) { msg = port.error.message; } self.connected = false; console.error(`native client connection failed: ${msg}`); browser.browserAction.setIcon({ path: iconDisconnected }); }; /** * Callback for successful connection to native application. * Logs a message to the console. */ self.onConnectedNative = () => { console.log('connected to native client'); browser.browserAction.setIcon({ path: iconConnected }); }; /** * Handle commands from native application. * @param {Object} msg - Data from native application. * @param {string} msg.id - Command/response ID. * @param {Object} msg.params - Arguments to command. */ self.receiveNative = msg => { console.log(`received:`, msg); let p = null; if ('command' in msg) { switch (msg.command) { case 'ping': p = self.ping(); break; // case 'all-windows': // p = self.allWindows(); // break; // case 'current-window': // p = self.currentWindow(); // break; case 'all-tabs': p = self.allTabs(); break; // DEPRECATED - replaced by self.tab(); unused by newer // versions 0.2.0+ of workflow // Remove from future versions case 'current-tab': p = self.tab(0); break; case 'tab': p = self.tab(msg.params); break; case 'all-bookmarks': p = self.allBookmarks(); break; case 'search-bookmarks': p = self.searchBookmarks(msg.params); break; case 'search-history': p = self.searchHistory(msg.params); break; case 'search-downloads': p = self.searchDownloads(msg.params); break; case 'activate-tab': p = self.activateTab(msg.params); break; case 'close-tabs-left': p = self.closeTabsLeft(msg.params); break; case 'close-tabs-right': p = self.closeTabsRight(msg.params); break; case 'close-tabs-other': p = self.closeTabsOther(msg.params); break; case 'execute-js': p = self.executeJS(msg.params); break; case 'run-bookmarklet': p = self.runBookmarklet(msg.params); break; case 'open-incognito': p = self.openIncognito(msg.params); break; default: console.error(`unknown command: ${msg.command}`); self.sendError(msg.id, 'unknown command'); return; } p.then(payload => { self.sendNative({ id: msg.id, payload: payload }); }).catch(err => { self.sendError(msg.id, err.message); }); } else { self.sendError(msg.id, 'no command given'); } }; /** * Send response to native application. * @param {Object} msg - Data to send to native application. * @param {string} msg.id - Command/response ID. * @param {string|bool|Object} msg.payload - Actual response data. * @param {string} msg.error - Error message if command failed. */ self.sendNative = msg => { if (self.nativePort) { self.nativePort.postMessage(msg) .then(resp => { console.log(`sent:`, msg); console.log(`response:`, resp); }) .catch(err => { console.error(`send error: ${err.message}`); }); } }; /** * Send error respones to native application. * @param {string} id - Command/response ID. * @param {string} msg - Error message. */ self.sendError = (id, msg) => { self.sendNative({ id: id, error: msg }); }; /** * Handle "ping" command. * @return {Promise} - Resolves to string "pong". */ self.ping = () => { return new Promise(resolve => { resolve('pong'); }); }; /** * Handle "all-tabs" command. * @return {Promise} - Resolves to array of Tab objects for all tabs. */ self.allTabs = () => { return browser.tabs.query({}).then(tabs => { return tabs.map(t => Tab(t)); }); }; /** * Handle "activate-tab" command. * @param {number} id - ID of tab to activate. */ self.activateTab = id => { return browser.tabs .update(id, { active: true }) .then(() => { return browser.tabs.get(id); }) .then(tab => { return browser.windows.update(tab.windowId, { focused: true }); }); }; /** * Handle "current-tab" command. * @return {Promise} - Resolves to Tab for current tab. * Throws an error if there is no current tab. */ // self.currentTab = () => { // return self.activeTab(null).then(t => { // if (!t) throw 'no current tab'; // let tab = Tab(t); // console.log(`[current-tab] ${tab}`); // return tab; // }); // }; /** * Handle "tab" command. * @param {number} tabId - ID of tab to return. * @return {Promise} - Resolves to Tab for current tab. * Throws an error if there is no current tab. */ self.tab = tabId => { if (!tabId) { return self.activeTab(null).then(t => { if (!t) throw 'no current tab'; let tab = Tab(t); console.log(`[current-tab] ${tab}`); return tab; }); } return browser.tabs .get(tabId) .then(t => { return Tab(t); }) }; /** * Handle "all-bookmarks" command. * @return {Promise} - Resolves to array of Bookmark objects for all bookmarks * and folders. */ self.allBookmarks = () => { let bookmarks = []; let addBookmarks = node => { if (node.url) bookmarks.push(Bookmark(node)); if (node.children) node.children.map(n => addBookmarks(n)); }; return browser.bookmarks.getTree().then(root => { addBookmarks(root[0]); return bookmarks; }); }; /** * Handle "search-bookmarks" command. * @param {string} query - Search query. * @return {Promies} - Resolves to array of Bookmark objects matching query. */ self.searchBookmarks = query => { return browser.bookmarks.search(query).then(nodes => { let bookmarks = nodes.filter(n => n.url).map(n => Bookmark(n)); console.debug(`${bookmarks.length} bookmark(s) for "${query}"`); return bookmarks; }); }; /** * Handle "search-history" command. * @param {string} query - Search query. * @return {Promies} - Resolves to array of History objects matching query. */ self.searchHistory = query => { return browser.history.search({ text: query, startTime: 0 }).then(items => { let history = items.filter(it => it.url).map(it => HistoryEntry(it)); console.debug(`${history.length} history item(s) for "${query}"`); return history; }); }; /** * Handle "search-downloads" command. * @param {string} query - Search query. * @return {Promise} - Resolves to array of Download objects matching query. */ self.searchDownloads = query => { return browser.downloads .search({ query: [query], exists: true, }) .then(items => { console.debug(`${items.length} download(s) for "${query}"`); return items.map(it => Download(it)); }); }; /** * Handle "close-tabs-left" command. * @param {number} tabId - ID of tab whose neighbours to close. * @return {Promise} - Result of browser.tabs.remove() */ self.closeTabsLeft = tabId => { console.debug(`closing tabs to left of tab #${tabId} ...`); let activeTab = null; return browser.tabs .get(tabId) .then(tab => { if (!tab) throw 'no current tab'; activeTab = tab; return browser.tabs.query({ windowId: tab.windowId }); }) .then(tabs => { let ids = tabs.filter(t => t.index < activeTab.index).map(t => t.id); return browser.tabs.remove(ids); }); }; /** * Handle "close-tabs-right" command. * @param {number} tabId - ID of tabs whose neighbours to close. * @return {Promise} - Result of browser.tabs.remove() */ self.closeTabsRight = tabId => { console.debug(`closing tabs to right of tab #${tabId} ...`); let activeTab = null; return browser.tabs .get(tabId) .then(tab => { if (!tab) throw 'no current tab'; activeTab = tab; return browser.tabs.query({ windowId: tab.windowId }); }) .then(tabs => { let ids = tabs.filter(t => t.index > activeTab.index).map(t => t.id); return browser.tabs.remove(ids); }); }; /** * Handle "close-tabs-other" command. * @param {number} tabId - ID of window to close tabs in. * @return {Promise} - Result of browser.tabs.remove() */ self.closeTabsOther = tabId => { console.debug(`closing other tabs in window of tab #${tabId} ...`); let activeTab = null; return browser.tabs .get(tabId) .then(tab => { activeTab = tab; return browser.tabs.query({ windowId: tab.windowId }); }) .then(tabs => { let ids = tabs.filter(t => t.id !== activeTab.id).map(t => t.id); return browser.tabs.remove(ids); }); }; /** Handle "execute-js" command. */ // self.executeJS = js => { // return browser.tabs.executeScript({ code: js }).then(results => { // console.debug(`js=${js}, results=`, results); // }); // }; /** * Handle "execute-js" command. * @param {Object} params - Tab and bookmarklet IDs. * @param {number} params.tabId - ID of tab to execute JS in. * If tabId is 0, JS is executed in the active tab. * @param {string} params.js - JavaScript to execute. */ self.executeJS = params => { console.debug(`execute-js`, params); var p; if (params.tabId) { p = browser.tabs.executeScript(params.tabId, { code: params.js }); } else { p = browser.tabs.executeScript({ code: params.js }); } return p.then(result => { return JSON.stringify(result); }); }; /** * Handle "run-bookmarklet" command. * @param {Object} params - Tab and bookmarklet IDs. * @param {number} params.tabId - ID of tab to execute bookmarklet in. * If tabId is 0, bookmarklet is executed in the active tab. * @param {string} params.bookmarkId - ID of bookmarklet to execute. */ self.runBookmarklet = params => { console.debug(`run-bookmarklet`, params); return browser.bookmarks.get(params.bookmarkId).then(bookmarks => { if (!bookmarks.length) throw 'bookmark not found'; let bm = bookmarks[0]; if (!bm.url.startsWith('javascript:')) throw 'not a bookmarklet'; let js = decodeURI(bm.url.slice(11)); if (params.tabId) browser.tabs.executeScript(params.tabId, { code: js }); else browser.tabs.executeScript({ code: js }); }); }; /** * Handle "open-incognito" command. * @param {string} url - URL to open in a new Incognito window. * @return {Promise} - Promise that resolves to null. */ self.openIncognito = url => { console.debug(`open-incognito ${url}`); return browser.windows.create({ incognito: true, url: url }); }; /** * Return active tab. * @param {number} winId - ID of window to get active tab of. * If 0 or null, current window is used. * @return {Promise} - Promise resolves to null or a tabs.Tab. */ self.activeTab = winId => { winId = winId || browser.windows.WINDOW_ID_CURRENT; return browser.tabs .query({ active: true, windowId: winId, }) .then(tabs => { if (tabs.length) return tabs[0]; return null; }); }; browser.runtime.onConnect.addListener(self.onConnected); self.connectNative(); console.log(`started`); }; browser.browserAction.setIcon({ path: iconDisconnected }); new Background();
  10. Can you help determine how to connect the extension to the workflow or what's preventing the extension from connecting to the workflow at the Firefox end? Not being a programmer, I don't have the first idea of what a stack trace is saying. I can follow instructions. I also have a second laptop set up almost identically, and it's got exactly the same error, so there's no new information there.
  11. I don't know exactly what this info implies, so I'm pasting the part from the log file that lists the first occurrence of the "dial unix" error. That Firefox extension debugger is totally beyond me. Is there some info from it I should post to shed light on the error? Should I post more of the log file? 18:51:57 [warning] info.plist not found. Guessed: /Users/e/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0 18:51:57 ----- Firefox Assistant/0.2.1 (AwGo/0.20.2) ------ 18:51:57 loaded URL action "Open in Firefox" from "~/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0/scripts/Open in Firefox.sh" 18:51:57 loaded URL action "Open in Safari" from "~/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0/scripts/Open in Safari.sh" 18:51:57 loaded URL action "Open in Chrome" from "~/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0/scripts/Open in Chrome.sh" 18:51:57 loaded URL action "Open in Default Application" from "~/Documents/var/computing/MacOS/Alfred/GRAY16/Alfred.alfredpreferences/workflows/user.workflow.159A6778-728D-47CD-8977-213AB04106F0/scripts/Open in Default Application.sh" 18:51:57 7.14249s since last check for update 18:51:57 searching bookmarks for "wor" ... 18:51:57 [ERROR] dial unix /tmp/alfred-firefox.501.sock: connect: no such file or directory 18:51:57 ------------------ FATAL ERROR ------------------- 18:51:57 Cannot Connect to Extension : goroutine 1 [running]: runtime/debug.Stack(0xc00011d990, 0x1, 0x1) /usr/local/opt/go/libexec/src/runtime/debug/stack.go:24 +0x9d github.com/deanishe/awgo.(*Workflow).Run.func2(0xc00014c000) /Users/daj/pkg/mod/github.com/deanishe/awgo@v0.22.1/workflow.go:343 +0xe7 panic(0x140f940, 0x1544170) /usr/local/opt/go/libexec/src/runtime/panic.go:679 +0x1b2 main.mustClient(0x14c15b5) /Users/daj/Code/Alfred/alfred-firefox-assistant/rpc_client.go:37 +0xb4 main.runBookmarks(0xc0000d2030, 0x0, 0x0, 0x0, 0x0) /Users/daj/Code/Alfred/alfred-firefox-assistant/client.go:249 +0xc1 github.com/peterbourgon/ff/ffcli.(*Command).Run(0x1831c40, 0xc0000d2030, 0x0, 0x0, 0x183a601, 0x2) /Users/daj/pkg/mod/github.com/peterbourgon/ff@v1.7.1-0.20200101221212-72e429b6ad42/ffcli/command.go:96 +0x248 github.com/peterbourgon/ff/ffcli.(*Command).Run(0x1832500, 0xc0000d2010, 0x3, 0x3, 0x14b6453, 0x9) /Users/daj/pkg/mod/github.com/peterbourgon/ff@v1.7.1-0.20200101221212-72e429b6ad42/ffcli/command.go:90 +0x1f1 main.run() /Users/daj/Code/Alfred/alfred-firefox-assistant/main.go:144 +0x191 github.com/deanishe/awgo.(*Workflow).Run(0xc00014c000, 0x14d4a18) /Users/daj/pkg/mod/github.com/deanishe/awgo@v0.22.1/workflow.go:357 +0x2af main.main() /Users/daj/Code/Alfred/alfred-firefox-assistant/main.go:149 +0x39 18:51:57 ---------------- END STACK TRACE -----------------
  12. I can't get the Firefox extension to connect. Its status always shows "disconnected." I installed the workflow first, then the extension via the workflow. I got through MacOS's security and privacy checks, no problem, but when I run the workflow, it seems to run correctly, but shows "Cannot connect to extension," which makes sense because the extension is always disconnected. I've tried re-starting Firefox. Any troubleshooting suggestions? EDIT: When doing ffass, under "No Connection to Browser," it says, "dial unix /tmp/alfred-firefox.501.sock: connect: no such file or directory"
  13. Yes, that worked, thanks. I see my mistake now: I cut and pasted from my Karabiner.json where the call to Alfred's workflow is in fact inside double quote, necessitating escaping the nested double quotes. But it still doesn't work as expected. When I do: $ /usr/bin/osascript -e 'tell application "Alfred 3" to run trigger "AstrillToggle-ext" in workflow "com.jimmy34742.alfred.AstrillToggle"' it opens Alfred's window with the workflow ready to run, and I still have to hit the return key to execute the workflow. How do I make that command line directly execute the workflow without opening Alfred's window and waiting for user input?
  14. When I do it without adding the single quotes as you suggested, I get this expected error: syntax error: Expected expression but found end of script. (-2741)
  15. Thanks for taking a look. That is indeed one of the variations I'd tried. When I do: /usr/bin/osascript -e 'tell application \"Alfred 3\" to run trigger \"AstrillToggle-ext\" in workflow \"com.jimmy34742.alfred.AstrillToggle\"' Terminal returns: syntax error: Expected expression, property or key form, etc. but found unknown token. (-2741) I've gone over it with a fine tooth comb, but I don't see any typos. I have several workflows that I've made external triggers for, and they work fine. When I run the workflow from Alfred, it works correctly.
×
×
  • Create New...