How to: Integrate Bash Function as External Tool

What is IntelliJ external tool?

It's a way to link an external command (eg. apple script or shell script) to run from IntelliJ. Allowing to assign a shortcut within IntelliJ for activation.

Next question: Why would You want to integrate a something like a bash function as an external tool?

Creating IntelliJ plugin is a much higher undertaking then being able to link up to some quick bash functionality.

Why go through apple script to use bash?

Use apple script to activate an existing terminal for the following reasons:

  • Allows usage of interactive commands such as fzf
  • Allows using preloaded bash environment avoiding having to source bash files and making the external tools work snappy.

How to do it:

Setup apple script

Create an apple script:

Example:

/Users/nkondrat/vintrin-env/IntelliJ/external_tools/fzf_file.applescript

With content like:

on run argv
  if (count of argv) = 0 then
    display alert "No file path provided!"
    return
  end if

  set filePath to item 1 of argv

  tell application "Terminal"
    activate
    do script "intellij_external_tools.fzf_for_file " & quoted form of filePath in front window
  end tell
end run

Note in above example my main Terminal driver is iTerm but I use Terminal for the external tool so that it can be positioned in a way to aligns with how I want it to appear for usage of external tool.

Setup bash function

intellij_external_tools.fzf_for_file is a bash function in my environment that is ready to accept a file.

Bash function
intellij_external_tools.fzf_for_file(){
  echo.func "${@}"

  intellij.for_given_file.open_at_line_using_fzf "${@}"
}
intellij.for_given_file.open_at_line_using_fzf ()
{
    echo.func "${@}";
    local file="${1:?file}";
    echo "${file:?}" | FileLineReferenceTabbed.create.from_piped_in.file_paths | FileLineReferenceTabbed.fzf | FileLineReferenceTabbed.open_in_intellij
}

Setup External Tool in IntelliJ

In Settings -> Tools -> External Tools add a new tool such as:

img

Notice how the program is osascript and the first argument is the script that we want to run. THe $FilePath$ is intellij provided argument (you can find a list of available arguments by clicking the + icon).

Note Worthy examples

Use existing terminal session without switching focus to it

Here just comment out (remove) 'activate' line in the apple script. And you will be able to perform actions on terminal session that already exists (all the sourcing has been done). Without loosing focus from IntelliJ.

on run argv
  if (count of argv) = 0 then
    display alert "No file path provided!"
    return
  end if

  set filePath to item 1 of argv

  tell application "Terminal"
--    activate

    do script "intellij_external_tools.copy_file_content_with_file_path " & quoted form of filePath in front window
  end tell
end run

Backlinks