Created
October 8, 2019 06:33
-
-
Save floriankraft/7ebd3e64360e76d586483452e69942c4 to your computer and use it in GitHub Desktop.
IntelliJ IDEA starting script for opening a project from the command line (e.g. with the command `idea <your-project-dir>`). Install it in: /usr/local/bin/idea - IntelliJ provides its own starting script, but it does not work flawlessly with Linux Mint.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import socket | |
import struct | |
import sys | |
import os | |
import time | |
# changed (2019-07-03) | |
import subprocess | |
# see com.intellij.idea.SocketLock for the server side of this interface | |
# Change paths according to your setup | |
RUN_PATH = u'/home/<user>/path/to/intellij-idea/current/bin/idea.sh' | |
CONFIG_PATH = u'/home/<user>/.IntelliJIdea2019.2/config' | |
SYSTEM_PATH = u'/home/<user>/.IntelliJIdea2019.2/system' | |
def print_usage(cmd): | |
print(('Usage:\n' + | |
' {0} -h | -? | --help\n' + | |
' {0} [project_dir]\n' + | |
' {0} [-l|--line line] [project_dir|--temp-project] file[:line]\n' + | |
' {0} diff <left> <right>\n' + | |
' {0} merge <local> <remote> [base] <merged>').format(cmd)) | |
def process_args(argv): | |
args = [] | |
skip_next = False | |
for i, arg in enumerate(argv[1:]): | |
if arg == '-h' or arg == '-?' or arg == '--help': | |
print_usage(argv[0]) | |
exit(0) | |
elif i == 0 and (arg == 'diff' or arg == 'merge' or arg == '--temp-project'): | |
args.append(arg) | |
elif arg == '-l' or arg == '--line': | |
args.append(arg) | |
skip_next = True | |
elif skip_next: | |
args.append(arg) | |
skip_next = False | |
else: | |
path = arg | |
if ':' in arg: | |
file_path, line_number = arg.rsplit(':', 1) | |
if line_number.isdigit(): | |
args.append('-l') | |
args.append(line_number) | |
path = file_path | |
args.append(os.path.abspath(path)) | |
return args | |
def try_activate_instance(args): | |
port_path = os.path.join(CONFIG_PATH, 'port') | |
token_path = os.path.join(SYSTEM_PATH, 'token') | |
if not (os.path.exists(port_path) and os.path.exists(token_path)): | |
return False | |
try: | |
with open(port_path) as pf: | |
port = int(pf.read()) | |
with open(token_path) as tf: | |
token = tf.read() | |
except (ValueError): | |
return False | |
s = socket.socket() | |
s.settimeout(0.3) | |
try: | |
s.connect(('127.0.0.1', port)) | |
except (socket.error, IOError): | |
return False | |
found = False | |
while True: | |
try: | |
path_len = struct.unpack('>h', s.recv(2))[0] | |
path = s.recv(path_len).decode('utf-8') | |
if os.path.abspath(path) == os.path.abspath(CONFIG_PATH): | |
found = True | |
break | |
except (socket.error, IOError): | |
return False | |
if found: | |
cmd = 'activate ' + token + '\0' + os.getcwd() + '\0' + '\0'.join(args) | |
if sys.version_info[0] >= 3: cmd = cmd.encode('utf-8') | |
encoded = struct.pack('>h', len(cmd)) + cmd | |
s.send(encoded) | |
time.sleep(0.5) # don't close the socket immediately | |
return True | |
return False | |
def start_new_instance(args): | |
if sys.platform == 'darwin': | |
if len(args) > 0: | |
args.insert(0, '--args') | |
os.execvp('/usr/bin/open', ['-a', RUN_PATH] + args) | |
else: | |
bin_file = os.path.split(RUN_PATH)[1] | |
# changed (2019-07-03) | |
# os.execv(RUN_PATH, [bin_file] + args) | |
FNULL = open(os.devnull, 'w') | |
subprocess.Popen([RUN_PATH] + args, stdout=FNULL, stderr=subprocess.STDOUT) | |
ide_args = process_args(sys.argv) | |
if not try_activate_instance(ide_args): | |
start_new_instance(ide_args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment