背景

我同时安装了 python2 和 python3 时,python 指向 python2,python3 才是 python3

默认情况下,在 Sublime 内 Ctrl/Cmd + B 运行 python 文件时,调用的是环境变量 PATH 中的 python

所以当我想用 python3 执行文件时,传统方法是先 new 一个 build system 专门运行 python3,每次还都得手动指定。极其繁琐!

需求

我希望 Sublime 可以根据 py 文件开头第一行注释 #!/usr/bin/env python3 来确定是执行 python2 还是 python3

解决方案

需要一个脚本,在 Sublime 调进 build system 时调用这个脚本

写一个新的 Python.sublime-build 文件,在这个文件中调用前面的脚本

用自己写的 Python.sublime-build 覆盖默认的 Python.sublime-build

具体步骤

  1. 找到 Python.sublime-package 文件,Mac 系统下在 /Applications/Sublime\ Text.app/Contents/MacOS/Packages/Python.sublime-package
  2. 把它复制一份到 ~/Library/Application\ Support/Sublime\ Text\ 3/Packages/User/ 下面,并把后缀改成 .zip
  3. 解压得到一个 Python 目录,进到这个目录,找到 Python.sublime-build 文件,装盘备用,一会下锅。
  4. 新建一个文件随便给个名字,保存在 ~/Library/Application\ Support/Sublime\ Text\ 3/Packages/User/ 下面,文件内容如下:
import sublime
import sublime_plugin import subprocess
import threading
import os class MyPyBuildCommand(sublime_plugin.WindowCommand): encoding = 'utf-8'
killed = False
proc = None
panel = None
panel_lock = threading.Lock() def is_enabled(self, kill=False):
# The Cancel build option should only be available
# when the process is still running
if kill:
return self.proc is not None and self.proc.poll() is None
return True def detect_version(self):
fname = self.window.active_view ().file_name()
with open(fname, 'r', encoding='utf-8') as f:
line = f.readline()
m = re.search(r'(python[0-9\.]*)', line)
if m and line.startswith("#"):
return m.group(1)
return "python" def run(self, kill=False):
if kill:
if self.proc is not None and self.proc.poll() is None:
self.killed = True
self.proc.terminate()
self.proc = None
return vars = self.window.extract_variables()
working_dir = vars['file_path'] # A lock is used to ensure only one thread is
# touching the output panel at a time
with self.panel_lock:
# Creating the panel implicitly clears any previous contents
self.panel = self.window.create_output_panel('exec') # Enable result navigation. The result_file_regex does
# the primary matching, but result_line_regex is used
# when build output includes some entries that only
# contain line/column info beneath a previous line
# listing the file info. The result_base_dir sets the
# path to resolve relative file names against.
settings = self.panel.settings()
settings.set(
'result_file_regex',
r'^File "([^"]+)" line (\d+) col (\d+)'
)
settings.set(
'result_line_regex',
r'^\s+line (\d+) col (\d+)'
)
settings.set('result_base_dir', working_dir) self.window.run_command('show_panel', {'panel': 'output.exec'}) if self.proc is not None and self.proc.poll() is None:
self.proc.terminate()
self.proc = None args = [ self.detect_version() ]
# sublime.message_dialog(vars['file_name'])
args.append(vars['file_name'])
env = os.environ.copy()
env["PYTHONUNBUFFERED"] = "1" # 及时 print
self.proc = subprocess.Popen(
args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=working_dir,
env=env,
)
self.killed = False threading.Thread(
target=self.read_handle,
args=(self.proc.stdout,)
).start() def read_handle(self, handle):
# for line in iter(handle.readline, b''):
# self.queue_write(line.decode(self.encoding))
# handle.close()
# return chunk_size = 2 ** 13
out = b''
while True:
try:
data = os.read(handle.fileno(), chunk_size)
# If exactly the requested number of bytes was
# read, there may be more data, and the current
# data may contain part of a multibyte char
out += data
if len(data) == chunk_size:
continue
if data == b'' and out == b'':
raise IOError('EOF')
# We pass out to a function to ensure the
# timeout gets the value of out right now,
# rather than a future (mutated) version
self.queue_write(out.decode(self.encoding))
if data == b'':
raise IOError('EOF')
out = b''
except (UnicodeDecodeError) as e:
msg = 'Error decoding output using %s - %s'
self.queue_write(msg % (self.encoding, str(e)))
break
except (IOError):
if self.killed:
msg = 'Cancelled'
else:
msg = 'Finished'
self.queue_write('\n[%s]' % msg)
break def queue_write(self, text):
sublime.set_timeout(lambda: self.do_write(text), 1) def do_write(self, text):
with self.panel_lock:
self.panel.run_command('append', {'characters': text})
  1. 修改第 3 步的那个 Python.sublime-build 文件:
{
"target": "my_py_build",
"selector": "source.python",
"cancel": {"kill": true}
}
  1. 随便测试一下



    and

  2. done!

  3. 有问题请留言

参考链接:

  1. https://stackoverflow.com/questions/51744019/how-to-open-sublime-package-file
  2. https://stackoverflow.com/questions/41768673/let-sublime-choose-among-two-similar-build-systems
  3. https://www.sublimetext.com/docs/3/build_systems.html
  4. 关于 PYTHONUNBUFFERED

sublime text build system automatic ctrl/cmd+B自动选择 python2 或 python3的更多相关文章

  1. Sublime Text Build System——编译运行Java

    今天Google如何在ST中编译运行Java的时候,无意中发现了一个更好的方法. 其实,在ST中是可以编译Java的,但是运行不了,因为没有配置运行命令.那么一般的配置方法都是如下的: http:// ...

  2. Custom Sublime Text Build Systems For Popular Tools And Languages

    Sublime Text is currently the text editor of choice for a number of developers in the open-source co ...

  3. Sublime Text Build 3065 License key

      Sublime Text Build 3065 License key 复制如下三个任意一个正版注册码即可 —– BEGIN LICENSE —– Andrew Weber Single User ...

  4. sublime C++ build system配置体验

    近期准备实习,于是终于步入了sublime的阵营,sublime确实性感. 在配置win7下C++编译运行集成环境的时候遇到点问题,于是接触了一下JSON格式,最后终于自己搞定了.. 参考文档:htt ...

  5. 最新版Sublime Text Build 3156 x64 的下载 + 注册码 + Install Package Control + 汉化教程

    一.Sublime Text  下载 神器 Sublime Text 最近开始更新到开发版本 Build 3156,本身英语不是太6,汉化党自然各种百度汉化教程,网上不是一堆绿色汉化包,就是让你下载汉 ...

  6. Sublime Text 3结合Chrome实现网页的自动刷新

    我们在编写前端代码时,写好一部分代码时想要看一看代码的实现效果,每次都要手动刷新会非常麻烦,神器来了,LiveReload插件实现网页的实时刷新,操作方法如下: 1. 官网下载Sublime Text ...

  7. Sublime Text Build 3207 x64 无法安装Package Control和插件

    两个问题的解决方法: 以下都是问题的解决,在本人电脑成功解决,还有就是在虚拟机上也成功解决,可以自行尝试下 . 测试电脑为win7-64位 问题1 : 安装Package Control失败 解决问题 ...

  8. sublime text 3 ,React,html元素自动补全方法(用Emmet写法写jsx中的html)

    1. 安装emmet: Preferences -> Package Control -> Install Package -> emmet 2. 配置emmet: Preferen ...

  9. Sublime Text 编译运行Kotlin

    Sublime Text 编译运行Kotlin 转 https://blog.csdn.net/pirate7777777/article/details/72655293 kotlin最近是火了,所 ...

随机推荐

  1. 《深入剖析Tomcat》源码

    <深入剖析Tomcat>翻译自<How Tomcat Works> 可以到官网下载:https://brainysoftware.com/download 官网下载比较慢,我就 ...

  2. 10分钟物联网设备接入阿里云IoT平台

    前言最近尝试了一下阿里云IoT物联网平台,还是蛮强大的.在此记录一下学习过程.本教程不需要任何外围硬件,一台电脑和一根能上网的网线即可.算是一篇Hello World了.先上效果图 第一章 准备工作1 ...

  3. mitmproxy第一次尝试-猿人学第九题

    启动 mitmdump -s http_proxy.py -p 9000 替换js代码 # -*- coding: utf-8 -*- import re main_url = 'http://mat ...

  4. MapReduce框架原理-InputFormat数据输入

    InputFormat简介 InputFormat:管控MR程序文件输入到Mapper阶段,主要做两项操作:怎么去切片?怎么将切片数据转换成键值对数据. InputFormat是一个抽象类,没有实现怎 ...

  5. git的实用命令(撤回,合并)

    前言 在用开发项目的时候,经常会写着写着会发现写错的时候,人生没有后悔药,但是git有啊,大不了从头再来嘛. git的一些撤销操作 代码还没有存到暂存区 当我们修改了一个文件,还没有执行git add ...

  6. 雪花算法ID在前端丢失精度解决方案

    首先说一下背景,目前笔者的工作是物联网方面的,设备有对应的智慧运营平台,平台开发中建表的主键用的是Mybatis plus默认的雪花算法来生成的,也就是分布式系统比较常用的雪花ID,技术栈就是常用的S ...

  7. 跟我一起写 Makefile(七)

    使用变量 ---- 在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方.其与C/C++所不同的是 ...

  8. FIFO 深度了解

    嘻哈第二篇,深度聊聊各种细节. 优化与跨时钟阈分析

  9. 一文学会在Markdown中编辑数学符号与公式

    在用Markdown写博客时会涉及到数学符号与公式的编辑,下面进行汇总.随手记录,方便你我他. 行内公式:将公式插入到本行内 $0.98^{365} \approx 0.0006$ 我的365天:\( ...

  10. kubebuilder实战之三:基础知识速览

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...