[英]Making Sublime Text 2 command on linux behave as it does on MacOS X
有很多问题要求从命令行访问Sublime Text 2编辑器。 总之,响应是使用符号链接,别名或简单的shell脚本来运行相应的sublime_text命令。 我能做到。 我想要的是使Linux版本的行为类似于MacOS版本。
在MacOS上,我有以下内容:
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl ~/bin/subl
然后在我的.zshrc中:
alias subl="$HOME/bin/subl -n"
export EDITOR="$HOME/bin/subl -n -w"
这样做有两件事。 它为我提供了一个subl
命令,用于在新窗口中打开命令行上给出的所有文件。 subl
命令不会阻止终端。 它还设置我的编辑器打开sublime文本来编辑参数,但这次它确实阻止了。 特别是$EDITOR
阻塞,直到它的参数被关闭。 它不会阻止不相关的sublime文本窗口。
我可以通过以下方式在linux上实现类似的效果:
在〜/ bin / subl中:
#! /bin/zsh
$HOME/Sublime\ Text\ 2/sublime_text -n $@ &
然后在〜/ bin / subl_wait :(想想TextMate用户的mate_wait
)
#! /bin/zsh
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $@
然后我可以将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
在~/bin/subl
:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n $@
在~/bin/subl_wait
:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $@
请注意,我到处都使用了-n
标志。 这可能不是你的一杯茶。 如果您使用-n
那么您可能还想查看close_windows_when_empty
设置。
受OP的回答启发,我为Sublime Text创建了一个bash
包装脚本,它包含了你在OSX和Linux上的所有发现和运行 。
它的目的有三个:
subl
CLI , subl
在subl
上与ST自己的subl
一样工作:调用ST 而不阻塞,除非明确请求等待 。 sublwait
链接为sublwait
,提供一个sublwait
CLI ,它自动应用--wait
和--wait
--new-window
选项,以使其适合与$EDITOR
一起使用 (注意某些程序,例如npm
,需要$EDITOR
仅包含可执行文件的名称 - 不支持可执行文件+选项); 还确保至少指定了一个文件。 唯一悬而未决的问题是,OP的避免竞争条件的方法 - sleep 1
- 是否足够强大。
更新 :请注意,OSX上的subl
默认情况下不会放在$PATH
- 您通常必须手动执行此操作。 如果你还没有这样做,脚本现在将在ST的应用程序包中找到subl
; (它按以下顺序尝试应用程序名称:'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.
请注意,如果您只使用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
在Ubuntu Gnu / Linux 13.04 64位:
我只是一直在运行subl。 所以我的git配置有: core.editor=/usr/bin/subl -n -w
这就是我所需要的一切。 我用ctrl-s保存git commit文件,用ctrl-w关闭窗口,我就完成了。 但是,我必须再通过点击页面右上角的X ... 96%的完美, 真正关闭窗口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.