Jump to content

Open Alfred file actioning from CLI


Recommended Posts

Is it possible to activate Alfred file action window from command line?

 

There is open command that is available to open a directory/file in Finder. I would love to have a command I can use on a file that will open a file actioning window in alfred. Say I have folder 'code' and I run 'alfred code' on it and this window shows : 

 

5987179183401_2017-08-06at15_19.png.2b5c6efcde4a4c8f7ce43787b1615912.png

 

This would be extremely handy to me. Is this possible? 

 

Thank you for any help.

Edited by nikivi
Link to comment

I came up with this code : 

function sf() {
  open $@
  osascript -e '
  tell application "System Events" to key code 98
  '
}

That should in theory, open file/directory in finder and then run a keystroke I use to open Alfred file viewer but it sends the keystroke straight away, not in the Finder window. :( 

Link to comment

This works : 

 

function sf() {
  open -R $@
  osascript -e '
    tell application "Keyboard Maestro Engine"
    do script "a: open file picker in alfred"
    end tell
  '
}

Activating this KM macro : 

 

59871e468b174_2017-08-06at15_48.png.2f7a9864a906c41a288ed080dae69ed7.png

 

If there is a non hackish way to do the same thing, it would be lovely. As right now, each time I use this command, it leaves a Finder window behind which is not good.

Edited by nikivi
Link to comment

Not exactly to open the File Action window, but this would make things easier and faster... Just make yourself a bash alias to open Alfred with the file path and then activate the File Action from Alfred (using your defined key binding)

 

Put in your '.bash_profile' (change 'alfreds' to the alias name that you prefer to use):

alfredSearch() { osascript -e 'tell application "Alfred 3" to search "'"$*"'"'; }
alias alfreds=alfredSearch

Or create a file in one of you bash path that is executable with this script inside:

#!/bin/bash
osascript -e 'tell application "Alfred 3" to search "'"$*"'"'

 

This has the advantage that you can open Alfred with any query that you want (not just file and folder), but you need to activate the File Action as a second action from Alfred

Link to comment
14 minutes ago, GuiB said:

osascript -e 'tell application "Alfred 3" to search "'"$*"'"'

 

Quoting different types of quotes makes the code incredibly hard to read. Instead, escape them: osascript -e "tell application \"Alfred 3\" to search \"$*\"".

 

On another note, @nikivi, from your screenshot you seem to be using incredibly outdated versions of my Workflows. That’s due to you changing their names and breaking the update feature, I gather.

Link to comment

Hey @vitor

 

I actually realised my mistake and just keep the original names of all workflows now. Strange that they were not updated. 

 

Will go through your alfred workflows repo, and get all the latest stuff. Shouldn't have changed names of workflows in the first place.

Edited by nikivi
Link to comment

Thanks @vitor for your recommendation!

 

@nikivi, here is new version of the scripts so you are set directly to the file or folder in Alfred (before you were set "into" it)

 

For the alias version:

alfredSearch() {
    filePath=$1
    if [[ -d $filePath ]] || [[ -f $filePath ]]; then
        dir=$(dirname "${1}")
        filename="${filePath##*/}"
        echo $filename | pbcopy
        osascript -e "tell application \"Alfred 3\" to search \"$dir"\" -e "delay 0.1" -e "tell application \"System Events\" to keystroke \"v\" using command down"
        # uncomment if prefer to keystroke the filename instead of using the clipboard and comment the two lines above
        # osascript -e "tell application \"Alfred 3\" to search \"$dir"\" -e "delay 0.1" -e "tell application \"System Events\" to keystroke \"$filename\""
    else
        osascript -e "tell application \"Alfred 3\" to search \"$*\""
        exit 1
    fi
}
alias alfreds=alfredSearch

 

For the script file version:

#!/bin/bash

filePath=$1
if [[ -d $filePath ]] || [[ -f $filePath ]]; then
    dir=$(dirname "${1}")
    filename="${filePath##*/}"
    echo $filename | pbcopy
    osascript -e "tell application \"Alfred 3\" to search \"$dir"\" -e "delay 0.1" -e "tell application \"System Events\" to keystroke \"v\" using command down"
    # uncomment if prefer to keystroke the filename instead of using the clipboard and comment the two lines above
    # osascript -e "tell application \"Alfred 3\" to search \"$dir"\" -e "delay 0.1" -e "tell application \"System Events\" to keystroke \"$filename\""
else
    osascript -e "tell application \"Alfred 3\" to search \"$*\""
    exit 1
fi

 

I think it's quite nice to have in the terminal! This could be set to pop Alfred with an action directly set from the terminal

Edited by GuiB
Link to comment

Try with my last scripts (those from my first post should work and don't know why your current terminal session quits, but those last scripts should be better for your use case)

 

As for why it quits... do you get error from you '~/.bash_profile' ?  or everything is set without complaint ? 

 

-- Edit

 

Try to run that line directly in your terminal to see if it makes an error:

osascript -e "tell application \"Alfred 3\" to search \"~\""

Do you see Alfred pop or an error ?

 

Or maybe try with:

/usr/bin/osascript -e "tell application \"Alfred 3\" to search \"~\""

 

Edited by GuiB
Link to comment
5 minutes ago, GuiB said:

Try with my last scripts (those from my first post should work and don't know why your current terminal session quits, but those last scripts should be better for your use case)

 

As for why it quits... do you get error from you '~/.bash_profile' ?  or everything is set without complaint ? 

 

This doesn't give the path though to the file/directory. For example if I run it on a file with alfreds script.sh, It will enter just that name prefixed with a dot for some reason although I don't see a dot specified anywhere in the script. 

 

Looks like this in the end : 

59874bdcac76a_2017-08-06at19_03.png.478b51f14987e2009fc1c1d14d43e882.png

 

Link to comment
4 minutes ago, nikivi said:

 

This doesn't give the path though to the file/directory. For example if I run it on a file with alfreds script.sh, It will enter just that name prefixed with a dot for some reason although I don't see a dot specified anywhere in the script. 

 

Looks like this in the end : 

59874bdcac76a_2017-08-06at19_03.png.478b51f14987e2009fc1c1d14d43e882.png

 

 

That because you need to give the full path of the file to the command (the command doesn't search inside your computer for where you have a file named script.sh)

Link to comment
7 minutes ago, nikivi said:

I was thinking I can use something like this perhaps : 

 

` filePath=$(readlink -f $1)`

 

I never used 'readlink', but from a little test, it seems that 'readlink' give you a relative path from your symbolic link to where it point to. So, that's why it returns a '.' . You would need to get the full path to the file you want to access

Link to comment

Thank you so much for the help @GuiB

 

This is the final function I am using though as it works quite nicely. 

function sf() {
  filePath=$(realpath "$1")
  osascript -e "tell application \"Alfred 3\" to search \""$filePath"\""
  osascript -e "tell application "System Events" to key code 98"
}

Aside from one thing. I can't run that second applescript it seems. Is it possible to issue F7 keystroke once the Alfred prompt pops up?

Link to comment
5 minutes ago, nikivi said:

Thank you so much for the help @GuiB

 

This is the final function I am using though as it works quite nicely. 


function sf() {
  filePath=$(realpath "$1")
  osascript -e "tell application \"Alfred 3\" to search \""$filePath"\""
  osascript -e "tell application "System Events" to key code 98"
}

Aside from one thing. I can't run that second applescript it seems. Is it possible to issue F7 keystroke once the Alfred prompt pops up?

 

It's because your quotes are not escaped

 

try that:

function sf() {
  filePath=$(realpath "$1")
  osascript -e "tell application \"Alfred 3\" to search \"$filePath\"" -e "tell application \"System Events\" to key code 98"
}

You may need a delay to wait that Alfred is in front:

function sf() {
  filePath=$(realpath "$1")
  osascript -e "tell application \"Alfred 3\" to search \"$filePath\"" -e "delay 0.1" -e "tell application \"System Events\" to key code 98"
}

 

Link to comment

Also this is a more robust version of the script  :)

function sf() {
  if [ $# -eq 0 ]; then
    filePath=$(pwd)
    osascript -e "tell application \"Alfred 3\" to search \"$filePath\""
   else
    filePath=$(realpath "$1")
    osascript -e "tell application \"Alfred 3\" to search \"$filePath\"" -e "delay 0.2" -e "tell application \"System Events\" to key code 98"
   fi
}

 

Edited by nikivi
Link to comment

Hi @nikivi, nice idea about the 'pwd' and 'realpath' commands!

 

I just had another look at my version so I have something set in my bash profile that is more complete.

 

There's 2 functions.

  • The first one is simpler as it mainly invoke Alfred as you would normally write in the Alfred popup, but by passing your arguments. It also tries to be smart with file path and working directory (thanks to your ideas).
  • The second works more like the Alfred File Selection action when invoked with the hotkey on a Finder selection. Therefore, it shows directly the Action Window for files and folders and tries to do it as well for a query that is not a path (ex: alfa activity monitor  ->  Would open the file action window of the Activity Monitor). Like the first one, it tries to be smart with file path and working directory.

 

A note to @nikivi, if you want to use my second function like yours, you should change the 'actionKey' to "key code 98" and the 'delayBetweenEvents' to 0.2 . Also, I think I found why your terminal sessions quits... I had an 'exit 1' in my previous script that shouldn't be there... it's now removed.

 

So, here are the functions to put in you bash_profile or to use in a script file:

 

# Alfred Search Function
alfs() {
    if [ $# -eq 0 ]; then   # If nothing is put as arguments open Alfred at the working directory so it list the content
        osascript -e "tell application \"Alfred 3\" to search \"$(pwd)\""
    elif [ $# -eq 1 ]; then # If only one argument is set
        if [[ -d $1 ]] || [[ -f $1 ]]; then   # if it looks like a path or file, then make sure we send a full path to Alfred
            osascript -e "tell application \"Alfred 3\" to search \"$(realpath "$1")\""
        else    # Any other words that are not a path would be sent to Alfred as is  (ex: alfs snip  ->  would open Alfred with "snip")
            osascript -e "tell application \"Alfred 3\" to search \"$*\""
        fi
    else   # If multiple arguments are set, then they are sent to Alfred as is. (ex: alfs define allo  ->  would pop Alfred with "define allo")
        osascript -e "tell application \"Alfred 3\" to search \"$*\""
    fi
}
# Alfred Action Function (pop the Action Window from Alfred - More like Alfred File Selection Hotkey when actioned on a selection in the Finder)
alfa() {
    actionKey="keystroke (ASCII character 29)"  # (meaning: right arrow) Put your prefered action key (Alfred -> File Search -> Actions -> Show Actions) as applescript command for keystroke or key code (ex: "key code 98")
    delayBetweenEvents=0.1    # Play with the number if the action doesn't work correctly
    if [ $# -eq 0 ]; then    # If no arguments, pop Alfred Action Window in the working directory
        filePath=$(pwd)
        osascript -e "tell application \"Alfred 3\" to search \"$filePath/"\" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to keystroke (ASCII character 8)" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to keystroke $actionKey"
    else
        filePath=$(realpath "$1")
        if [[ -d $filePath ]]; then    # If it's a directory path, make sure it's a full path and open the Alfred Action Window on it
            osascript -e "tell application \"Alfred 3\" to search \"$filePath/"\" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to keystroke (ASCII character 8)" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to keystroke $actionKey"
        elif [[ -f $filePath ]]; then    # If it's a file path, make sure it's a full path and open the Alfred Action Window on it
            osascript -e "tell application \"Alfred 3\" to search \"$filePath\"" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to $actionKey"
        else  # If there's more than one argument, search as is and try to access the Alfred Action Window. The Action Window should pop if it's possible, or the standard Alfred Search would be shown (ex: alfa activity monitor  ->  Would open the file action window of the Activity Monitor)
            osascript -e "tell application \"Alfred 3\" to search \"$*\"" -e "delay $delayBetweenEvents" -e "tell application \"System Events\" to $actionKey"
        fi
    fi
}

 

Edited by GuiB
updated script to remove the use of the clipboard when access the Action Window with a directory
Link to comment

Could you also make queries via AppleScript work the same way as they do in Alfred?

 

I mean, if I enter "~/Desktop" into Alfred, it filters the contents of ~/ by keyword "Desktop". If I enter "~/Desktop/" (with a trailing slash), Alfred shows the contents of ~/Desktop.

 

If I pass a path via AppleScript, and it's a directory that exists, Alfred adds the trailing slash automatically and shows me the contents of ~/Desktop.

 

It'd be useful if Alfred didn't mess with the query, so I can enter "~/Desktop" to remain in ~/, but with the folder "Desktop" selected, or I can enter "~/Desktop/" (with a trailing slash) to enter the directory in Alfred.

Link to comment

@deanishe this is by design, and the behaviour is consistent with pasting a path into Alfred. It allows you to copy a path from e.g. pwd in terminal (which doesn't have a trailing space), paste it into Alfred and it will browse the same folder as your terminal session. If you paste ~/Desktop or ~/Desktop/ into Alfred, it will browse both, as these are treated as actual paths (the path is interpreted and resolved before the filtering within the file system navigation view).

 

It is in fact just a side effect of Alfred recognising the search term as a path and navigating into it which is why the navigation is happening from AppleScript. The AppleScript search command is showing Alfred's default window with the specified search term (which happens to be a path), this search term is passed to the framework which is interpreting it as a path and then replacing the view out with the file system navigation view (you can actually see it flicker as the views change if you look closely).

 

A tidier solution could be to add additional new AppleScript:

tell application "Alfred 3" to browse "~/Desktop"

This would open the navigation view directly, skipping the path recognition and processing via Alfred's default results view.

 

Cheers,

Andrew

Link to comment
2 hours ago, Andrew said:

this is by design, and the behaviour is consistent with pasting a path into Alfred

 

I know, and I'd rather Alfred didn't do that. It makes it so that you can't select a directory directly, only browse one.

 

It's also inconsistent: if I pass a filepath, Alfred selects it. If I pass a directory path, Alfred enters it.

 

If I want to browse the directory, I could append the trailing slash, just like I would if I were typing the query into Alfred.

Link to comment

@deanishe the behaviour in Alfred's default results won't change (and therefore the AppleScript behaviour for "search" won't change).

 

The new "browse" AppleScript command will open the navigation window and just use string you pass, so you'll be able to add a trailing slash or not depending on what you want.

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...