在Linux上制作Sublime Text 2命令的行为与在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命令不会阻塞terminal。 它也设置我的编辑器打开崇高的文本编辑参数,但这次它阻止。 特别是, $EDITOR块直到它的参数被closures。 它不会阻止不相关的崇高文本窗口。

我可以通过以下方法在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正在等待,直到所有打开的文件被closures,而不仅仅是它的参数。

是否有可能使这个工作完美?

看起来我发现了这个问题。 (感谢这篇文章: http : //www.sublimetext.com/forum/viewtopic.php?f=2& t= 7003 )

基本点:崇高的行为有所不同,取决于一个实例是否已经运行!

如果一个实例已经运行,那么在Linux上崇高的行为就像MacOS一样。 如果没有实例在运行,那么终端将阻塞,直到你退出崇高。

考虑到这一点,我们只需要修改脚本以确保崇高运行:

~/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 ,像ST在自己的OSX上的subl一样工作: 除非等待被明确请求,否则不要阻塞,直接调用ST。
  • 在Linux上封装与等待相关的错误解决方法
  • 当保存或sublwait链接为sublwait ,提供一个sublwait CLI自动应用 – --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 - eg, /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%完美。