Reputation: 35
I am using Ubuntu 16.04. I use Sublime Text 3, and I can compile c++ program and run it in terminal. The following is the script.
{
"cmd": ["g++", "$file", "-o", "${file_path}/${file_base_name}"],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c, source.c++, source.cxx, source.cpp",
"variants":
[
{
"name": "RunInShell",
"shell": true,
"cmd": ["gnome-terminal -e 'bash -c \"${file_path}/${file_base_name};echo; echo Press ENTER to continue; read line;exit; exec bash\"'"]
}
]
}
BUT, when the path of c++ program contains space(like /algorithms/Search in Rotated Sorted Array
), the script doesn't work!
bash: /media/algorithms/Search: No such file or directory
shows in the terminal, when I using RunInShell.
I am trying to modify the script, like insert single quotes.
"cmd": ["gnome-terminal -e 'bash -c \"'${file_path}/${file_base_name}';echo; echo Press ENTER to continue; read line;exit; exec bash\"'"]
But it doesn't work .
I wonder how to modify the script to make it work well.
Upvotes: 1
Views: 1017
Reputation: 16065
Therefore, we can escape each space to a backslash and a space, for use in Bash. It may be easier to play around with it outside the build system first, for example by typing the following in ST's (Python) console:
import os.path; file_path = '/algorithms/Search in Rotated Sorted Array'; file_name = os.path.basename(file_path); sublime.expand_variables(r'${file_path/ /\\ /g}/${file_base_name/ /\\ /g}', { 'file_path': os.path.dirname(file_path), 'file': file_path, 'file_name': file_name, 'file_extension': os.path.splitext(file_name)[1], 'file_base_name': os.path.splitext(file_name)[0], 'packages': sublime.packages_path() })
Note that the above includes more variables than we actually need, but doesn't actually include all the variables available from the build system, but it is enough for this example and they can easily be added if you want to experiment further. Check the ST API Reference for more info, specifically the missing items are part of the Window
class.
Anyway, the output we get from that is:
'/algorithms/Search\\ in\\ Rotated\\ Sorted\\ Array'
(Remember that this is a Python string, so two slashes is an escape code that represents a single slash.)
So what we see here is ${file_path/ /\\\\ /g}
. What this tells ST, is to take the value of the file_path
variable and run a regex substitution on it. It should replace a space with a literal slash followed by a space. The /g
at the end is the global regex modifier flag, to tell it to not stop at the first match/replacement, to make sure it replaces all spaces.
Now, to plug that into your build system:
"cmd": ["gnome-terminal -e 'bash -c \"${file_path/ /\\\\ /g}/${file_base_name/ /\\\\ /g};echo; echo Press ENTER to continue; read line;exit; exec bash\"'"]
Note that we have 4 slashes - both in the Python code I showed to test with and the JSON string. This is because the first two slashes is an escape sequence that tells JSON/Python to use a literal slash. Then we want to do the same again, so that the regex pattern will use a literal slash.
Upvotes: 3