use*_*209 7 linux sublimetext2
有很多问题要求从命令行访问Sublime Text 2编辑器.总之,响应是使用符号链接,别名或简单的shell脚本来运行相应的sublime_text命令.我能做到.我想要的是使linux版本的行为类似于MacOS版本.
在MacOS上,我有以下内容:
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl ~/bin/subl
Run Code Online (Sandbox Code Playgroud)
然后在我的.zshrc中:
alias subl="$HOME/bin/subl -n"
export EDITOR="$HOME/bin/subl -n -w"
Run Code Online (Sandbox Code Playgroud)
这样做有两件事.它给了我一个subl命令,打开在新窗口中命令行上给出的任何文件.该subl命令不会阻止终端.它还设置我的编辑器打开sublime文本来编辑参数,但这次它确实阻止了.特别是,$EDITOR在其参数关闭之前阻塞.它不会阻止不相关的sublime文本窗口.
我可以通过以下方式在linux上实现类似的效果:
在〜/ bin/subl中:
#! /bin/zsh
$HOME/Sublime\ Text\ 2/sublime_text -n $@ &
Run Code Online (Sandbox Code Playgroud)
然后在〜/ bin/subl_wait中:(想想mate_waitTextMate用户)
#! /bin/zsh
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $@
Run Code Online (Sandbox Code Playgroud)
那么我可以设置EDITOR到subl_wait,事情差不多的工作. subl打开文件进行编辑,不会阻止. subl_wait打开文件进行编辑并阻止.
问题是subl_wait等待所有打开的文件都关闭,而不仅仅是它的参数.
有可能让这个工作完美吗?
看起来我发现了这个问题.(感谢这篇文章:http://www.sublimetext.com/forum/viewtopic.php?f = 2& t = 7003)
基本点:sublime的行为有所不同,具体取决于实例是否已在运行!
如果一个实例已在运行,则linux上的sublime与MacOS的行为类似.如果没有实例正在运行,则终端将阻塞,直到您退出sublime.
考虑到这一点,我们只需要修改脚本以确保sublime正在运行:
在~/bin/subl_start:
#! /bin/zsh
if [ ! "$(pidof sublime_text)" ] ; then
# start sublime text main instance
# echo "Starting Sublime Text 2"
$HOME/Sublime\ Text\ 2/sublime_text &
sleep 1 # needed to avoid a race condition
fi
Run Code Online (Sandbox Code Playgroud)
在~/bin/subl:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n $@
Run Code Online (Sandbox Code Playgroud)
在~/bin/subl_wait:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $@
Run Code Online (Sandbox Code Playgroud)
请注意,我-n到处都使用过这些标志.这可能不是你的一杯茶.如果您正在使用,-n那么您可能还想查看您的close_windows_when_empty设置.
受OP的回答启发,我bash 为Sublime Text创建了一个包装脚本,它包含了所有的发现并在OSX和Linux上运行.
它的目的有三个:
sublCLI,它subl在STX上就像ST一样:在不阻塞的情况下调用ST ,除非明确请求等待.sublwait,提供一个自动应用和选项的sublwaitCLI,以使其适合使用(请注意,某些程序,例如,要求仅包含可执行文件的名称 - 不支持可执行文件+选项); 还确保至少指定了一个文件.--wait--new-window$EDITORnpm$EDITOR唯一尚未解决的问题是OP是否采取了避免竞争条件的方法sleep 1- 足够强大.
更新:请注意,sublOSX默认情况下不会放在$PATH- 您通常必须手动执行此操作.如果您还没有这样做,脚本现在将subl在ST的应用程序包中找到; (它按以下顺序尝试应用程序名称:'Sublime Text','Sublime Text 2','Sublime Text 3',先进入/Applications,然后进入~/Applications.)
以下是运行脚本的输出-h:
Multi-platform (OSX, Linux) wrapper script for invocation of Sublime Text (ST)
from the command line.
Linux:
Works around undesired blocking of the shell (unless requested)
and a bug when waiting for specific files to be edited.
Both platforms:
When invoked as `sublwait`, automatically applies the
--wait --new-window
options to make it suitable for use with $EDITOR.
Therefore, you can to the following:
- Name this script `subl` for a CLI that supports ALL options.
(On OSX, this will simply defer to the `subl` CLI that came with ST.)
- Place the script in a directory in your $PATH.
- In the same directory, create a symlink to the `subl` script named
`sublwait`:
ln -s subl sublwait
and, if desired, add
export EDITOR=sublwait
to your shell profile.
Run Code Online (Sandbox Code Playgroud)
请注意,如果您只使用OSX,您可以使用ST自己的操作subl,只需将此脚本直接保存为sublwait.
#!/usr/bin/env bash
# Multi-platform (OSX, Linux) wrapper script for invocation of Sublime Text (ST)
# from the command line. Invoke with -h for details.
[[ $1 == '-h' || $1 == '--help' ]] && showHelpOnly=1 || showHelpOnly=0
[[ $(basename "$BASH_SOURCE") == 'sublwait' ]] && invokedAsSublWait=1 || invokedAsSublWait=0
[[ $(uname) == 'Darwin' ]] && isOsX=1 || isOsX=0
# Find the platform-appropriate ST executable.
if (( isOsX )); then # OSX: ST comes with a bona-fide CLI, `subl`.
# First, try to find the `subl` CLI in the $PATH.
# Note: This CLI is NOT there by default; it must be created by symlinking it from
# its location inside the ST app bundle.
# Find the `subl` executable, ignoring this script, if named subl' as well, or a
# script by that name in the same folder as this one (when invoked via symlink 'sublwait').
stExe=$(which -a subl | fgrep -v -x "$(dirname "$BASH_SOURCE")/subl" | head -1)
# If not already in the path, look for it inside the application bundle. Try several locations and versions.
if [[ -z $stExe ]]; then
for p in {,$HOME}"/Applications/Sublime Text"{,' 2',' 3'}".app/Contents/SharedSupport/bin/subl"; do
[[ -f $p ]] && { stExe=$p; break; }
done
fi
[[ -x $stExe ]] || { echo "ERROR: Sublime Text CLI 'subl' not found." 1>&2; exit 1; }
else # Linux: `sublime_text` is the only executable - the app itself.
stExe='sublime_text'
which "$stExe" >/dev/null || { echo "ERROR: Sublime Text executable '$stExe' not found." 1>&2; exit 1; }
fi
# Show command-line help, if requested.
# Add preamble before printing ST's own help.
# Note that we needn't worry about blocking the
# shell in this case - ST just outputs synchronously
# to stdout, then exits.
if (( showHelpOnly )); then
bugDescr=$(
cat <<EOF
works around a bug on Linux (as of v2.0.2), where Sublime Text,
if it is not already running, mistakenly blocks until it is exited altogether.
EOF
)
if (( invokedAsSublWait )); then
# We provide variant-specific help here.
cat <<EOF
Wrapper script for Sublime Text suitable for use with the \$EDITOR variable.
Opens the specified files for editing in a new window and blocks the
invoking program (shell) until they are closed.
In other words: the --wait and --new-window options are automatically
applied.
Aside from encapsulating this functionality without the need for options
- helpful for tools that require \$EDITOR to be an executable name only -
$bugDescr
Usage: sublwait file ...
EOF
# Note: Adding other options doesn't make sense in this scenario
# (as of v2.0.2), so we do NOT show ST's own help here.
else
cat <<EOF
Multi-platform (OSX, Linux) wrapper script for invocation of
Sublime Text (ST) from the command line.
Linux:
Works around undesired blocking of the shell (unless requested)
and a bug when waiting for specific files to be edited.
Both platforms:
When invoked as \`sublwait\`, automatically applies the
--wait --new-window
options to make it suitable for use with \$EDITOR.
Therefore, you can to the following:
- Name this script \`subl\` for a CLI that supports ALL options.
(On OSX, this will simply defer to the \`subl\` CLI that came with ST.)
- Place the script in a directory in your \$PATH.
- In the same directory, create a symlink to the \`subl\` script named
\`sublwait\`:
ln -s subl sublwait
and, if desired, add
export EDITOR=sublwait
to your shell profile.
Sublime Text's own help:
------------------------
EOF
# Finally, print ST's own help and exit.
exec "$stExe" "$@"
fi
exit 0
fi
# Invoked as `sublwait`? -> automatically apply --wait --new-window options.
if (( invokedAsSublWait )); then
# Validate parameters.
# - We expect NO options - to keep things simple and predictable, we do NOT allow
# specifying additional options (beyond the implied ones).
# - We need at least 1 file argument.
# - As a courtesy, we ensure that no *directories* are among the arguments - ST doesn't support
# that properly (always waits for ST exit altogether); beyond that, however, we leave input
# validation to ST.
if [[ "$1" =~ ^-[[:alnum:]]+$ || "$1" =~ ^--[[:alnum:]]+[[:alnum:]-]+$ ]]; then # options specified?
{ echo "ERROR: Unexpected option specified: '$1'. Use -h for help." 1>&2; exit 1; }
elif (( $# == 0 )); then # no file arguments?
{ echo "ERROR: Missing file argument. Use -h for help." 1>&2; exit 1; }
else # any directories among the arguments?
# Note: We do NOT check for file existence - files could be created on demand.
# (Things can still go wrong - e.g., /nosuchdir/mynewfile - and ST doesn't
# handle that gracefully, but we don't want to do too much here.)
for f in "$@"; do
[[ ! -d "$f" ]] || { echo "ERROR: Specifying directories is not supported: '$f'. Use -h for help." 1>&2; exit 1; }
done
fi
# Prepend the implied options.
set -- '--wait' '--new-window' "$@"
fi
# Finally, invoke ST:
if (( isOsX )); then # OSX
# `subl` on OSX handles all cases correctly; simply pass parameters through.
exec "$stExe" "$@"
else # LINUX: `sublime_text`, the app executable itself, does have a CLI, but it blocks the shell.
# Determine if the wait option was specified.
mustWait=0
if (( invokedAsSublWait )); then
mustWait=1
else
# Look for the wait option in the parameters to pass through.
for p in "$@"; do
[[ $p != -* ]] && break # past options
[[ $p == '--wait' || $p =~ ^-[[:alnum:]]*w[[:alnum:]]*$ ]] && { mustWait=1; break; }
done
fi
if (( mustWait )); then # Invoke in wait-for-specified-files-to-close mode.
# Quirk on Linux:
# If sublime_text isn't running yet, we must start it explicitly first.
# Otherwise, --wait will wait for ST *as a whole* to be closed before returning,
# which is undesired.
# Thanks, http://stackoverflow.com/questions/14598261/making-sublime-text-2-command-on-linux-behave-as-it-does-on-macos-x
if ! pidof "$stExe" 1>/dev/null; then
# Launch as BACKGROUND task to avoid blocking.
# (Sadly, the `--background` option - designed not to activate the Sublime Text window
# on launching - doesn't actually work on Linux (as of ST v2.0.2 on Ubuntu 12.04).)
("$stExe" --background &)
# !! We MUST give ST some time to start up, otherwise the 2nd invocation below will be ignored.
# ?? Does a fixed sleep time of 1 second work reliably?
sleep 1
fi
# Invoke in blocking manner, as requested.
exec "$stExe" "$@"
else # Ensure invocation in NON-blocking manner.
if ! pidof "$stExe" 1>/dev/null; then # ST isn't running.
# If ST isn't running, invoking it *always* blocks.
# Therefore, we launch it as a background taks.
# Invocation via a subshell (parentheses) suppresses display of the
# background-task 'housekeeping' info.
("$stExe" "$@" &)
else # ST is already running, we can safely invoke it directly without fear of blocking.
exec "$stExe" "$@"
fi
fi
fi
Run Code Online (Sandbox Code Playgroud)