背景

我同时安装了 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. 选择排序(selection_sort)——Python实现

      # 选择排序 # 作用:对给出的n个顺序不定的数进行排序 # 输入:任意数组A # 输出:按顺序排列的数组A # 时间复杂度 (n(n-1))/2 # 选择排序 # 第一趟:选择第一个元素,依次与 ...

  2. jvm源码解读--18 Java的start()方法解读 以及 wait 和notify流程图

    drawwed by 张艳涛 and get info from openjdk8 还有一个图

  3. linux统计nginx日志中请求访问量命令

    Nginx 三种分配策略:轮询.权重.ip_hash(比如你登录了一个网站,登录信息已经保存到 a 机器,但当你做后续操作时的请求会到 b 机器,那么就获取不到你原来登录的信息,此时你就需要重新登录了 ...

  4. 嵌套div的onClick事件问题

    嵌套div的onClick事件问题我在下面的代码中的外层div中加了onClick事件,这样当鼠标点击这个div的时候就会跳转了.但是我在图片上加了一些其他效果,所以当鼠标点击中间的img时不能触发跳 ...

  5. fastjson 1.2.24 反序列化导致任意命令执行漏洞

    漏洞检测 区分 Fastjson 和 Jackson {"name":"S","age":21} 和 {"name":& ...

  6. 开机时自动启动的AutoHotkey脚本

    ;;; 开机时自动启动的AutoHotkey脚本;; 此脚本修改时间 2019年06月18日20时48分;; 计时器创建代码段 ------------------------------------ ...

  7. 3.python编程与计算机的关系,如何执行python文件

    上一节预告了这一章想讲如何不停地和世界打招呼,这涉及到编程中一个重要的概念:循环. 但经过了两周断更后细想了一下,不行,我们得对上一章进行补充,而且这个补充非常关键!也印证了上一章所说的: 上一节章很 ...

  8. 手脱UPX壳的方法

    0X00    了解 upx UPX作为一款元老级PE加密壳,在以前的那个年代盛行,著名病毒[熊猫烧香]就是使用这款加密壳. 0X01    单步跟踪法 就是使用ollydbg加载程序后,按F8进行单 ...

  9. MySQL-02-体系结构

    MySQL体系结构 c/s模型介绍 连接MySQL # TCP/IP方式(远程.本地) mysql -uroot -pAlnk123 -h 10.0.0.51 -P3306 # Socket方式(仅本 ...

  10. Longhorn 企业级云原生分布式容器存储-券(Volume)和节点(Node)

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生分布式块存储解决方案设计架构和概念 Longhorn 企业级云原生容器存储解决方 ...