背景

我同时安装了 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/ 下面,文件内容如下:
  1. import sublime
  2. import sublime_plugin
  3. import subprocess
  4. import threading
  5. import os
  6. class MyPyBuildCommand(sublime_plugin.WindowCommand):
  7. encoding = 'utf-8'
  8. killed = False
  9. proc = None
  10. panel = None
  11. panel_lock = threading.Lock()
  12. def is_enabled(self, kill=False):
  13. # The Cancel build option should only be available
  14. # when the process is still running
  15. if kill:
  16. return self.proc is not None and self.proc.poll() is None
  17. return True
  18. def detect_version(self):
  19. fname = self.window.active_view ().file_name()
  20. with open(fname, 'r', encoding='utf-8') as f:
  21. line = f.readline()
  22. m = re.search(r'(python[0-9\.]*)', line)
  23. if m and line.startswith("#"):
  24. return m.group(1)
  25. return "python"
  26. def run(self, kill=False):
  27. if kill:
  28. if self.proc is not None and self.proc.poll() is None:
  29. self.killed = True
  30. self.proc.terminate()
  31. self.proc = None
  32. return
  33. vars = self.window.extract_variables()
  34. working_dir = vars['file_path']
  35. # A lock is used to ensure only one thread is
  36. # touching the output panel at a time
  37. with self.panel_lock:
  38. # Creating the panel implicitly clears any previous contents
  39. self.panel = self.window.create_output_panel('exec')
  40. # Enable result navigation. The result_file_regex does
  41. # the primary matching, but result_line_regex is used
  42. # when build output includes some entries that only
  43. # contain line/column info beneath a previous line
  44. # listing the file info. The result_base_dir sets the
  45. # path to resolve relative file names against.
  46. settings = self.panel.settings()
  47. settings.set(
  48. 'result_file_regex',
  49. r'^File "([^"]+)" line (\d+) col (\d+)'
  50. )
  51. settings.set(
  52. 'result_line_regex',
  53. r'^\s+line (\d+) col (\d+)'
  54. )
  55. settings.set('result_base_dir', working_dir)
  56. self.window.run_command('show_panel', {'panel': 'output.exec'})
  57. if self.proc is not None and self.proc.poll() is None:
  58. self.proc.terminate()
  59. self.proc = None
  60. args = [ self.detect_version() ]
  61. # sublime.message_dialog(vars['file_name'])
  62. args.append(vars['file_name'])
  63. env = os.environ.copy()
  64. env["PYTHONUNBUFFERED"] = "1" # 及时 print
  65. self.proc = subprocess.Popen(
  66. args,
  67. stdin=subprocess.PIPE,
  68. stdout=subprocess.PIPE,
  69. stderr=subprocess.STDOUT,
  70. cwd=working_dir,
  71. env=env,
  72. )
  73. self.killed = False
  74. threading.Thread(
  75. target=self.read_handle,
  76. args=(self.proc.stdout,)
  77. ).start()
  78. def read_handle(self, handle):
  79. # for line in iter(handle.readline, b''):
  80. # self.queue_write(line.decode(self.encoding))
  81. # handle.close()
  82. # return
  83. chunk_size = 2 ** 13
  84. out = b''
  85. while True:
  86. try:
  87. data = os.read(handle.fileno(), chunk_size)
  88. # If exactly the requested number of bytes was
  89. # read, there may be more data, and the current
  90. # data may contain part of a multibyte char
  91. out += data
  92. if len(data) == chunk_size:
  93. continue
  94. if data == b'' and out == b'':
  95. raise IOError('EOF')
  96. # We pass out to a function to ensure the
  97. # timeout gets the value of out right now,
  98. # rather than a future (mutated) version
  99. self.queue_write(out.decode(self.encoding))
  100. if data == b'':
  101. raise IOError('EOF')
  102. out = b''
  103. except (UnicodeDecodeError) as e:
  104. msg = 'Error decoding output using %s - %s'
  105. self.queue_write(msg % (self.encoding, str(e)))
  106. break
  107. except (IOError):
  108. if self.killed:
  109. msg = 'Cancelled'
  110. else:
  111. msg = 'Finished'
  112. self.queue_write('\n[%s]' % msg)
  113. break
  114. def queue_write(self, text):
  115. sublime.set_timeout(lambda: self.do_write(text), 1)
  116. def do_write(self, text):
  117. with self.panel_lock:
  118. self.panel.run_command('append', {'characters': text})
  1. 修改第 3 步的那个 Python.sublime-build 文件:
  1. {
  2. "target": "my_py_build",
  3. "selector": "source.python",
  4. "cancel": {"kill": true}
  5. }
  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. intouch 趋势图Y轴自适应功能完善

    在项目中有利用到历史趋势,其y轴往往展示的是该点的最小/最大值范围,对于曲线波动展示不够友好.故而利用自带方法进行完善,以此记录. Histrend1.MinRange=HTGetAutoScaleV ...

  2. js之检测浏览器

    getBrowser () { let ua = navigator.userAgent.toLocaleLowerCase() let browserType = null if (ua.match ...

  3. 【Azure 应用服务】App Service 运行状况健康检查功能简介 (Health check)

    通过Azure App Service门户,启用Health Check来监视应用服务的实例,当发现其中一个实例处于不健康(unhealthy)状态时,通过重新路由(即把有问题的实例从负载均衡器中移除 ...

  4. C语言复习(二)

    引言: 不会将每一个部分都详述,只关注于一些自己认为重要的或常错的,若有不足,还望指出 switch()细节:括号内必须是整型或枚举类型:遇到break才会跳出:case包含的必须是常量 contin ...

  5. Vue3学习第一例:Vue3架构入门

    入门 Vue3的教程很少,官方网站实例不好整,另外由于Python的Django也掌握了,学习这个有些让人眼乱.Vue项目创建后,在public目录下面自动生成了一个index.htm,里面有个div ...

  6. Vulhub-DC-4靶场

    Vulhub-DC-4靶场 前言 这套靶场的亮点在于对hydra的运用比较多,在遇到大容量字典的时候,BurpSuite可能会因为设置的运行内存的限制,导致字典需要花很长时间导入进去,虽然通过修改配置 ...

  7. 制作Java桌面程序的一键安装包

    一.简介 这个打包程序主要包含了对Java程序的普通打包.对程序的管理员权限设置.因为自己打包的时候要求程序在32位操作系统和64位操作系统下都能使用,所以有些打包步骤和设置都不相同.打包过程中主要使 ...

  8. matplotlib.pyplot设置画布主题

    import matplotlib.pyplot as plt # 定义一个画图函数 def sinplot(flip = 1): x = np.linspace(0,10,100) for i in ...

  9. SpringBoot开发二十一-发送私信

    发送私信功能开发: 功能开发 数据访问层 message-mapper.xml 增加 <insert id="insertMessage" parameterType=&qu ...

  10. STM32—位带操作

    STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见. 51 单片机中通过关键字 sbit 来实现位定义, STM32 ...