├── foo.html
├── repllibs
└── __init__.py
├── .no-sublime-package
├── .gitignore
├── .hgignore
├── messages.json
├── __init__.py
├── doc
├── _static
│ ├── menu.png
│ └── palette.png
├── make.bat
├── Makefile
└── conf.py
├── config
├── OCaml
│ ├── OCaml (toplevel).sublime-settings
│ ├── Default.sublime-commands
│ ├── OCaml (toplevel).tmLanguage
│ └── Main.sublime-menu
├── F
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── R
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Perl
│ ├── re.pl
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Io
│ ├── Default.sublime-commands
│ ├── Main.sublime-menu
│ ├── repl.io
│ └── Io.tmLanguage
├── Lua
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── PHP
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── SML
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── GDB
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── NodeJS
│ ├── Default.sublime-commands
│ ├── Main.sublime-menu
│ └── repl.js
├── Shell
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Elixir
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Erlang
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Groovy
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Matlab
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Octave
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Rails
│ ├── Default.sublime-commands
│ ├── Main.sublime-menu
│ └── pry_repl.rb
├── Haskell
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Maxima
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── MozRepl
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Racket
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Tower
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── ScriptCS
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── PowerShell
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Prolog
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Execnet
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── CoffeeScript
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Sublime
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Clojure
│ ├── Default.sublime-keymap
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Scala
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Ruby
│ ├── Default.sublime-commands
│ ├── pry_repl.rb
│ └── Main.sublime-menu
├── ClojureScript
│ ├── Default.sublime-commands
│ ├── clojurescript.tmLanguage
│ └── Main.sublime-menu
├── Scheme
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Main.sublime-menu.template
├── Python
│ ├── Default.sublime-commands
│ ├── ipy_repl.py
│ └── Main.sublime-menu
└── CommonLisp
│ ├── Default.sublime-commands
│ └── Main.sublime-menu
├── Default.sublime-commands
├── SublimeREPL (OSX).sublime-settings
├── repls
├── killableprocess
│ ├── __init__.py
│ └── qijo.py
├── __init__.py
├── telnet_repl.py
├── autocomplete_server.py
├── sublimepython_repl.py
├── powershell_repl.py
├── execnet_repl.py
├── repl.py
├── sublimehaskell_repl.py
├── sublimeutop_repl.py
└── subprocess_repl.py
├── LICENSE.TXT
├── Context.sublime-menu
├── packages.json
├── sublimerepl_build_system_hack.sublime-build
├── sublimerepl_build_system_hack.py
├── LICENSE-LIB.txt
├── completions.py
├── run_existing_command.py
├── Main.sublime-menu
├── messages
└── 2.0.0.txt
├── README.md
├── SublimeREPL.sublime-settings
├── Default (Windows).sublime-keymap
├── Default (Linux).sublime-keymap
├── Default (OSX).sublime-keymap
├── lang_integration.py
└── text_transfer.py
/foo.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/repllibs/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.no-sublime-package:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.bak
3 | doc/_build
4 |
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 | *.pyc
3 | doc/_build/*
4 |
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "2.0.0": "messages/2.0.0.txt"
3 | }
4 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
--------------------------------------------------------------------------------
/doc/_static/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuub/SublimeREPL/HEAD/doc/_static/menu.png
--------------------------------------------------------------------------------
/doc/_static/palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuub/SublimeREPL/HEAD/doc/_static/palette.png
--------------------------------------------------------------------------------
/config/OCaml/OCaml (toplevel).sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "auto_complete_triggers": [ {"selector": "source.ocaml", "characters": "."} ]
3 | }
4 |
--------------------------------------------------------------------------------
/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Restart REPL",
4 | "command": "repl_restart"
5 | }
6 | ]
7 |
--------------------------------------------------------------------------------
/SublimeREPL (OSX).sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | // Add to PATH /usr/local/bin by default on OSX.
3 | "default_extend_env": {"PATH": "{PATH}:/usr/local/bin"}
4 | }
5 |
--------------------------------------------------------------------------------
/repls/killableprocess/__init__.py:
--------------------------------------------------------------------------------
1 | from .killableprocess import Popen, mswindows
2 | if mswindows:
3 | from .winprocess import STARTUPINFO, STARTF_USESHOWWINDOW
--------------------------------------------------------------------------------
/LICENSE.TXT:
--------------------------------------------------------------------------------
1 | The whole SublimeREPL package is licensed under GNU GENERAL PUBLIC LICENSE Version 2.
2 |
3 | Parts of SublimeREPL might be usable under more permisive terms. See LICENSE-LIB.txt for details.
4 |
--------------------------------------------------------------------------------
/Context.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {"caption": "-"},
3 | {"command": "repl_kill", "caption": "Kill"},
4 | {"command": "repl_restart", "caption": "Restart"},
5 | {"command": "subprocess_repl_send_signal", "caption": "Send other SIGNAL"}
6 | ]
--------------------------------------------------------------------------------
/config/F/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: F#",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_f#",
7 | "file": "config/F/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/R/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: R",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_r",
7 | "file": "config/R/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Perl/re.pl:
--------------------------------------------------------------------------------
1 | $| = 1;
2 |
3 | while(true) {
4 | print "perl> ";
5 | $line=<>;
6 | $value=eval($line);
7 | $error=$@;
8 | if( $error ne "" ) {
9 | print $error;
10 | } else {
11 | print "$value\n";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/config/Io/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Io",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_io",
7 | "file": "config/Io/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Lua/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Lua",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_lua",
7 | "file": "config/Lua/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/PHP/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: PHP",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_php",
7 | "file": "config/PHP/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/SML/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: SML",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_sml",
7 | "file": "config/SML/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/GDB/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: GDB",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_gdb",
7 | "file": "config/GDB/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/NodeJS/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Node",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_node",
7 | "file": "config/NodeJS/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Shell/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Shell",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_shell",
7 | "file": "config/Shell/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Elixir/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Elixir",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_elixir",
7 | "file": "config/Elixir/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Erlang/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Erlang",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_erlang",
7 | "file": "config/Erlang/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Groovy/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Groovy",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_groovy",
7 | "file": "config/Groovy/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Matlab/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Matlab",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_matlab",
7 | "file": "config/Matlab/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Octave/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Octave",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_octave",
7 | "file": "config/Octave/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Perl/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Perl",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_Perl",
7 | "file": "config/Perl/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Rails/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Rails",
4 | "command": "run_existing_window_command",
5 | "args": {
6 | "id": "repl_rails",
7 | "file": "config/Rails/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Haskell/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Haskell",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_haskell",
7 | "file": "config/Haskell/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Maxima/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Maxima",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_maxima",
7 | "file": "config/Maxima/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/MozRepl/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: MozRepl",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_mozrepl",
7 | "file": "config/MozRepl/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Racket/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Racket",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_plt_racket",
7 | "file": "config/Racket/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Tower/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Tower Console",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_tower",
7 | "file": "config/Tower/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/repls/__init__.py:
--------------------------------------------------------------------------------
1 | from .repl import *
2 | from .subprocess_repl import *
3 | from .sublimehaskell_repl import *
4 | from .telnet_repl import *
5 | from .sublimepython_repl import *
6 | from .powershell_repl import *
7 | from .sublimeutop_repl import *
8 | # from .execnet_repl import * # disabled for now
9 |
--------------------------------------------------------------------------------
/config/ScriptCS/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: ScriptCS",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_scriptcs",
7 | "file": "config/ScriptCS/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/PowerShell/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: PowerShell",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_powershell",
7 | "file": "config/PowerShell/Main.sublime-menu"
8 | }
9 | }
10 | ]
--------------------------------------------------------------------------------
/config/Prolog/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Prolog (Sicstus)",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_prolog",
7 | "file": "config/Prolog/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Execnet/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Python - execnet",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_sublime_execnet",
7 | "file": "config/Execnet/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/CoffeeScript/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: CoffeeScript",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_coffeescript",
7 | "file": "config/CoffeeScript/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Sublime/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Python - Sublime Text Console",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_sublime_python",
7 | "file": "config/Sublime/Main.sublime-menu"
8 | }
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/config/Clojure/Default.sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["ctrl+f12", "c", "s"], "command": "run_existing_window_command", "args": {"id": "repl_clojure", "file": "config/Clojure/Main.sublime-menu"}},
3 | { "keys": ["ctrl+f12", "c", "t"], "command": "run_existing_window_command", "args": {"id": "repl_clojure_telnet", "file": "config/Clojure/Main.sublime-menu"}}
4 | ]
--------------------------------------------------------------------------------
/packages.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema_version": "3.0.0",
3 | "packages": [{
4 | "name": "SublimeREPL",
5 | "details": "https://github.com/wuub/SublimeREPL",
6 | "description": "SublimeREPL - run an interpreter inside ST2 (Clojure, CoffeeScript, F#, Groovy, Haskell, Lua, MozRepl, NodeJS, Python + virtualenv, R, Ruby, Scala...)",
7 | "releases": [
8 | {
9 | "sublime_text": "*",
10 | "tags": true
11 | }
12 | ]
13 | }]
14 | }
15 |
--------------------------------------------------------------------------------
/config/Scala/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Scala",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_scala",
7 | "file": "config/Scala/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: SBT for opened folder",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_sbt",
15 | "file": "config/Scala/Main.sublime-menu"
16 | }
17 | }
18 | ]
--------------------------------------------------------------------------------
/sublimerepl_build_system_hack.sublime-build:
--------------------------------------------------------------------------------
1 | {
2 | "target": "sublimerepl_build_system_hack",
3 | "cmd": {
4 | "file_path": "${file_path}",
5 | "file": "${file}",
6 | "file_name": "${file_name}",
7 | "file_extension": "${file_extension}",
8 | "file_base_name": "${file_base_name}",
9 | "packages": "${packages}",
10 | "project": "${project}",
11 | "project_path": "${project_path}",
12 | "project_name": "${project_name}",
13 | "project_extension": "${project_extension}",
14 | "project_base_name": "${project_base_name}"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/config/OCaml/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: OCaml",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_ocaml",
7 | "file": "config/OCaml/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: OCaml utop",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_ocaml_utop",
15 | "file": "config/OCaml/Main.sublime-menu"
16 | }
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/config/Ruby/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Ruby",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_ruby",
7 | "file": "config/Ruby/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: Ruby IRB (deprecated)",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_ruby_irb",
15 | "file": "config/Ruby/Main.sublime-menu"
16 | }
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/config/Clojure/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Clojure",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_clojure",
7 | "file": "config/Clojure/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: Clojure-Telnet",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_clojure_telnet",
15 | "file": "config/Clojure/Main.sublime-menu"
16 | }
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/config/ClojureScript/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: ClojureScript Browser REPL",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_clojurescript_browser",
7 | "file": "config/ClojureScript/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: ClojureScript",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_clojurescript",
15 | "file": "config/ClojureScript/Main.sublime-menu"
16 | }
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/config/Execnet/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children": [
10 | {"caption": "Python",
11 | "id": "Python",
12 | "children": [
13 | {
14 | "command": "execnet_virtualenv_repl",
15 | "id": "repl_sublime_execnet",
16 | "caption": "Python - execnet"
17 | }
18 | ]}
19 | ]}
20 | ]
21 | }]
22 |
--------------------------------------------------------------------------------
/config/Sublime/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Sublime",
13 | "id": "repl_sublime_python",
14 | "args": {
15 | "type": "sublime_python",
16 | "encoding": "utf8",
17 | "syntax": "Packages/Python/Python.tmLanguage"
18 | }
19 | }
20 | ]
21 | }]
22 | }
23 | ]
24 |
--------------------------------------------------------------------------------
/config/ClojureScript/clojurescript.tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | comment
6 | ClojureScript
7 | name
8 | ClojureScript
9 | fileTypes
10 |
11 | cljs
12 |
13 | patterns
14 |
15 |
16 | include
17 | source.clojure
18 |
19 |
20 | scopeName
21 | source.clojurescript
22 |
23 |
--------------------------------------------------------------------------------
/config/GDB/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "GDB",
13 | "id": "repl_gdb",
14 | "mnemonic": "D",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["gdb"],
19 | "cwd": "$file_path",
20 | "external_id": "gdb"
21 | }
22 | }
23 | ]
24 | }]
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/config/Maxima/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Maxima",
13 | "id": "repl_maxima",
14 | "mnemonic": "M",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["maxima"],
19 | "cwd": "$file_path",
20 | "external_id": "maxima"
21 | }
22 | }
23 | ]
24 | }]
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/config/MozRepl/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "MozRepl",
13 | "mnemonic": "M",
14 | "id": "repl_mozrepl",
15 | "args": {
16 | "type": "telnet",
17 | "encoding": "utf8",
18 | "host":"localhost",
19 | "port": 4242,
20 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage"
21 | }
22 | }
23 | ]
24 | }]
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/config/SML/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "SML",
13 | "id": "repl_sml",
14 | "args": {
15 | "type": "subprocess",
16 | "encoding": "utf8",
17 | "cmd": ["sml"],
18 | "cwd": "$file_path",
19 | "external_id": "sml",
20 | "syntax": "Packages/SML (Standard ML)/sml.tmLanguage"
21 | }
22 | }
23 | ]
24 | }]
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/config/Scheme/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Scheme",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_scheme",
7 | "file": "config/Scheme/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: Gauche",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_gauche",
15 | "file": "config/Scheme/Main.sublime-menu"
16 | }
17 | },
18 | {
19 | "caption": "SublimeREPL: Petite Chez Scheme",
20 | "command": "run_existing_window_command", "args":
21 | {
22 | "id": "repl_petite",
23 | "file": "config/Scheme/Main.sublime-menu"
24 | }
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/config/Lua/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Lua",
13 | "id": "repl_lua",
14 | "mnemonic": "L",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["lua", "-i"],
19 | "cwd": "$file_path",
20 | "external_id": "lua",
21 | "syntax": "Packages/Lua/Lua.tmLanguage"
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Haskell/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Haskell",
13 | "id": "repl_haskell",
14 | "mnemonic": "H",
15 | "args": {
16 | "type": "sublime_haskell",
17 | "encoding": "utf8",
18 | "cmd": ["ghci"],
19 | "cwd": "$file_path",
20 | "external_id": "haskell",
21 | "syntax": "Packages/Haskell/Haskell.tmLanguage"
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Matlab/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Matlab",
13 | "id": "repl_matlab",
14 | "mnemonic": "M",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["matlab", "-nodesktop","-nosplash"],
19 | "cwd": "$file_path",
20 | "external_id": "matlab",
21 | "syntax": "Packages/Matlab/Matlab.tmLanguage"
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Prolog/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id":"tools",
4 | "children":[
5 | {
6 | "caption":"SublimeREPL",
7 | "mnemonic":"r",
8 | "id":"SublimeREPL",
9 | "children":[
10 | {
11 | "caption":"Prolog (Sicstus)",
12 | "command":"repl_open",
13 | "id":"repl_prolog",
14 | "mnemonic":"P",
15 | "args":{
16 | "type":"subprocess",
17 | "external_id":"prolog",
18 | "encoding":"utf8",
19 | "cmd": ["sicstus"],
20 | "soft_quit":"\nexit\n",
21 | "cwd":"$file_path",
22 | "cmd_postfix":"\n",
23 | "autocomplete_server": true,
24 | "syntax":"Packages/Prolog/Prolog.tmLanguage"
25 | }
26 | }
27 | ]
28 | }
29 | ]
30 | }
31 | ]
32 |
--------------------------------------------------------------------------------
/config/Elixir/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "id": "repl_elixir",
13 | "caption": "Elixir",
14 | "args": {
15 | "type": "subprocess",
16 | "encoding": "utf8",
17 | "cmd": ["iex"],
18 | "cwd": "$file_path",
19 | "syntax": "Packages/Elixir/Elixir.tmLanguage",
20 | "external_id": "elixir",
21 | "extend_env": {"NODE_DISABLE_COLORS": "1"}
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Erlang/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "id": "repl_erlang",
13 | "caption": "Erlang",
14 | "args": {
15 | "type": "subprocess",
16 | "encoding": "utf8",
17 | "cmd": ["erl", "-i"],
18 | "cwd": "$file_path",
19 | "syntax": "Packages/Erlang/Erlang.tmLanguage",
20 | "external_id": "erlang",
21 | "extend_env": {"NODE_DISABLE_COLORS": "1"}
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Perl/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Perl",
13 | "id": "repl_Perl",
14 | "mnemonic": "P",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["perl","${packages}/SublimeREPL/config/Perl/re.pl"],
19 | "cwd": "$file_path",
20 | "external_id": "perl",
21 | "syntax": "Packages/Perl/Perl.tmLanguage"
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/PowerShell/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "PowerShell",
13 | "id": "repl_powershell",
14 | "mnemonic": "P",
15 | "args": {
16 | "type": "powershell",
17 | "encoding": "",
18 | "cmd": ["powershell", "-"],
19 | "cwd": "$file_path",
20 | "external_id": "powershell",
21 | "syntax": "Packages/PowerShell/Support/PowershellSyntax.tmLanguage"
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/Octave/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Octave",
13 | "id": "repl_octave",
14 | "mnemonic": "O",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["octave", "-i"],
19 | "cwd": "$file_path",
20 | "external_id": "octave",
21 | "additional_scopes": ["matlab"],
22 | "syntax": "Packages/Matlab/Matlab.tmLanguage"
23 | }
24 | }
25 | ]
26 | }]
27 | }
28 | ]
29 |
--------------------------------------------------------------------------------
/sublimerepl_build_system_hack.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
2 |
3 | import sublime_plugin
4 | try:
5 | import queue
6 | except ImportError:
7 | import Queue as queue
8 |
9 | RESULTS = None
10 | HACK_BUILD_SYSTEM = "Packages/SublimeREPL/sublimerepl_build_system_hack.sublime-build"
11 | AUTOMATIC_BUILD_SYSTEM = ""
12 |
13 |
14 | class SublimereplBuildSystemHackCommand(sublime_plugin.WindowCommand):
15 | def run(self, cmd):
16 | RESULTS.put(cmd)
17 |
18 |
19 | def get_project_settings(window):
20 | global RESULTS
21 | try:
22 | RESULTS = queue.Queue() # in case of garbage on RESULTS
23 | window.run_command("set_build_system", {"file": HACK_BUILD_SYSTEM})
24 | window.run_command("build")
25 | finally:
26 | window.run_command("set_build_system", {"file": AUTOMATIC_BUILD_SYSTEM})
27 | return RESULTS.get(timeout=1.0)
28 |
--------------------------------------------------------------------------------
/config/Tower/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "id": "repl_tower",
13 | "caption": "Tower Console",
14 | "args": {
15 | "cwd": "$file_path",
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["tower", "console", "-c"],
19 | "syntax": "Packages/CoffeeScript/CoffeeScript.tmLanguage",
20 | "external_id": "tower",
21 | "extend_env": {"NODE_DISABLE_COLORS": "1"}
22 | }
23 | }
24 | ]
25 | }]
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/CoffeeScript/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "id": "repl_coffeescript",
13 | "caption": "CoffeeScript",
14 | "args": {
15 | "type": "subprocess",
16 | "encoding": "utf8",
17 | "cmd": ["coffee", "-i"],
18 | "cwd": "$file_path",
19 | "syntax": "Packages/CoffeeScript/CoffeeScript.tmLanguage",
20 | "external_id": "coffeescript",
21 | "additional_scopes": ["coffee"],
22 | "extend_env": {"NODE_DISABLE_COLORS": "1"}
23 | }
24 | }
25 | ]
26 | }]
27 | }
28 | ]
29 |
--------------------------------------------------------------------------------
/config/Racket/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children": [
5 | {
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children": [
10 | {
11 | "command": "repl_open",
12 | "caption": "Racket",
13 | "id": "repl_plt_racket",
14 | "mnemonic": "R",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": ["racket"],
19 | "cwd": "$file_path",
20 | "syntax": "Packages/Racket/Racket.tmLanguage",
21 | "external_id": "racket"
22 | }
23 | }
24 | ]
25 | }
26 | ]
27 | }
28 | ]
--------------------------------------------------------------------------------
/LICENSE-LIB.txt:
--------------------------------------------------------------------------------
1 | LICENSE Libraries and external dependencies
2 |
3 | SublimeREPL is not a monolithic block of code and some REPLs / functions depends on external libraries.
4 |
5 | This means that, although the parts of SublimeREPL that I (wuub) wrote are published under BSD license and you're free to reuse them as you wish, the whole SublimeREPL package is as of now licensed under GPLv2.
6 |
7 | - Remote Python depends on a fantastic execnet library by Holger Krekel (https://bitbucket.org/hpk42/execnet & http://codespeak.net/execnet/ & https://twitter.com/hpk42. execnet is licensed under GPLv2. As a result repls/execnet_repl.py and lang_integration:ExecnetVirtualenvRepl are licensed under GPLv2 as well!
8 |
9 | - Persistent history depends on buzhug library by Pierre Quentel. (http://buzhug.sourceforge.net/ buzhug is published under the revised BSD licence.
10 |
11 | - subprocess_repl depends on killableprocess by Peter Astrand, Mike Taylor and Mikeal Rogers. Please see killableprocess.py for details.
12 |
--------------------------------------------------------------------------------
/config/ScriptCS/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "ScriptCS",
13 | "id": "repl_scriptcs",
14 | "mnemonic": "C",
15 | "args": {
16 | "type": "subprocess",
17 | "external_id": "scriptcs",
18 | "encoding": "utf8",
19 | "cmd": {
20 | "windows": ["scriptcs"],
21 | "osx": ["scriptcs"],
22 | "linux": ["scriptcs"]},
23 | "cwd": "$file_path",
24 | "additional_scopes": ["csx"],
25 | "syntax": "Packages/scriptcs/ScriptCs.tmLanguage"
26 | }
27 | }
28 | ]
29 | }]
30 | }
31 | ]
32 |
--------------------------------------------------------------------------------
/config/F/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "F#",
13 | "id": "repl_f#",
14 | "mnemonic": "F",
15 | "args": {
16 | "type": "subprocess",
17 | "external_id": "fsharp",
18 | "encoding": "utf8",
19 | "cmd": {
20 | "windows": ["fsi.exe", "--utf8output", "--gui-"],
21 | "osx": ["fsharpi", "--utf8output", "--readline-"],
22 | "linux": ["fsi", "--utf8output", "--readline-"]},
23 | "cmd_postfix": ";;\n",
24 | "cwd": "$file_path",
25 | "syntax": "Packages/F#/F#.tmLanguage"
26 | }
27 | }
28 | ]
29 | }]
30 | }
31 | ]
32 |
--------------------------------------------------------------------------------
/config/PHP/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "PHP",
13 | "id": "repl_php",
14 | "mnemonic": "P",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": {"windows": "$win_cmd_encoding",
18 | "linux": "utf-8",
19 | "osx": "utf-8"},
20 | "cmd": {"windows": ["php.exe", "-a"],
21 | "linux": ["php", "-a"],
22 | "osx": ["php", "-a"]},
23 | "cwd": "$file_path",
24 | "cmd_postfix": "\n",
25 | "env": {},
26 | "suppress_echo": false,
27 | "syntax": "Packages/Text/Plain text.tmLanguage"
28 | }
29 | }
30 | ]
31 | }]
32 | }
33 | ]
34 |
--------------------------------------------------------------------------------
/config/Main.sublime-menu.template:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | // {"command": "repl_open",
12 | // "caption": "Command Caption in Menu",
13 | // "mnemonic": "m",
14 | // "args": {
15 | // "type": "subprocess|telnet",
16 | // "encoding": "utf8",
17 | // "cmd": ["bash", "-i"] or "bash -i" on windows,
18 | // "cwd": "$file_path",
19 | // "env": {}, // clean environment for subprocess repl
20 | // "extend_env": {}, // variables to be added to standard env
21 | // "cmd_postfix": "\n", // postfix that will be automatically added after a line in repl
22 | // "suppress_echo": false, // try to remove remote echo
23 | // "syntax": "Packages/Text/Plain text.tmLanguage"
24 | // }
25 | // },
26 | ]
27 | }]
28 | }
29 | ]
30 |
--------------------------------------------------------------------------------
/config/NodeJS/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Node",
13 | "id": "repl_node",
14 | "mnemonic": "N",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": {"linux": ["node", "${packages}/SublimeREPL/config/NodeJS/repl.js"],
19 | "osx": ["node", "${packages}/SublimeREPL/config/NodeJS/repl.js"],
20 | "windows": ["node.exe", "${packages}/SublimeREPL/config/NodeJS/repl.js"]},
21 | "cwd": "$file_path",
22 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage",
23 | "external_id": "js",
24 | "autocomplete_server": true,
25 | "extend_env": {"NODE_NO_READLINE": 1}
26 | }
27 | }
28 | ]
29 | }]
30 | }
31 | ]
32 |
--------------------------------------------------------------------------------
/config/Python/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Python",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_python",
7 | "file": "config/Python/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: Python - PDB current file",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_python_pdb",
15 | "file": "config/Python/Main.sublime-menu"
16 | }
17 | },
18 | {
19 | "caption": "SublimeREPL: Python - RUN current file",
20 | "command": "run_existing_window_command", "args":
21 | {
22 | "id": "repl_python_run",
23 | "file": "config/Python/Main.sublime-menu"
24 | }
25 | },
26 | {
27 | "command": "python_virtualenv_repl",
28 | "caption": "SublimeREPL: Python - virtualenv"
29 | },
30 | {
31 | "caption": "SublimeREPL: Python - IPython",
32 | "command": "run_existing_window_command", "args":
33 | {
34 | "id": "repl_python_ipython",
35 | "file": "config/Python/Main.sublime-menu"
36 | }
37 | }
38 | ]
39 |
--------------------------------------------------------------------------------
/config/Shell/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Shell",
13 | "id": "repl_shell",
14 | "mnemonic": "S",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": {"windows": "$win_cmd_encoding",
18 | "linux": "utf-8",
19 | "osx": "utf-8"},
20 | "cmd": {"windows": ["cmd.exe"],
21 | "linux": ["bash", "-i"],
22 | "osx": ["bash", "-i"]},
23 | "cwd": "$file_path",
24 | "cmd_postfix": "\n",
25 | "env": {},
26 | "suppress_echo": true,
27 | "external_id": "shell",
28 | "syntax": "Packages/Text/Plain text.tmLanguage"
29 | }
30 | }
31 | ]
32 | }]
33 | }
34 | ]
35 |
--------------------------------------------------------------------------------
/config/Io/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "Io",
13 | "id": "repl_io",
14 | "mnemonic": "I",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "cmd": {"linux": ["io", "${packages}/SublimeREPL/config/Io/repl.io"],
19 | "windows": ["io", "${packages}/SublimeREPL/config/Io/repl.io"],
20 | "osx": ["io", "${packages}/SublimeREPL/config/Io/repl.io"]},
21 | "cwd": "$file_path",
22 | "external_id": "io",
23 | "suppress_echo": {"linux": true,
24 | "windows": false,
25 | "osx": true},
26 | "syntax": "Packages/SublimeREPL/config/Io/Io.tmLanguage"
27 | }
28 | }
29 | ]
30 | }]
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/config/NodeJS/repl.js:
--------------------------------------------------------------------------------
1 | (function () {
2 |
3 | var repl = require('repl');
4 |
5 | var rep = repl.start({
6 | prompt: null, //'> ',
7 | source: null, //process.stdin,
8 | eval: null, //require('vm').runInThisContext,
9 | useGlobal: true, //false
10 | useColors: false
11 | });
12 |
13 |
14 | var net = require('net');
15 | var ac_port = process.env.SUBLIMEREPL_AC_PORT;
16 | var client = new net.Socket();
17 | client.connect(ac_port, "localhost", function() {});
18 |
19 | client.on('data', function(data) {
20 | var strData = data.toString();
21 | var index = strData.indexOf(":");
22 | var json = strData.slice(index+1, strData.length - 1)
23 | var inData = JSON.parse(json);
24 | var wordIndex = inData.line.slice(inData.cursor_pos).search(/\b/);
25 | if(wordIndex !== 0){
26 | inData.line = inData.line.slice(0, inData.cursor_pos);
27 | }
28 |
29 | var send = function (_, completions) {
30 | var comps = completions[0];
31 | var msg = JSON.stringify([inData.line, comps]);
32 | var payload = msg.length + ":" + msg + ",";
33 | client.write(payload)
34 | }
35 | rep.rli.completer(inData.line, send);
36 | });
37 |
38 | })();
39 |
--------------------------------------------------------------------------------
/completions.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
2 |
3 | import sublime
4 | import sublime_plugin
5 |
6 |
7 |
8 | class SublimeREPLCompletions(sublime_plugin.EventListener):
9 | def on_query_completions(self, view, prefix, locations):
10 | try:
11 | from .sublimerepl import manager
12 | except ValueError:
13 | from sublimerepl import manager
14 |
15 | if not view.settings().get("repl"):
16 | return True
17 |
18 | rv = manager.repl_view(view)
19 | if not rv:
20 | return []
21 |
22 | repl = rv.repl
23 | if not repl.autocomplete_available():
24 | return []
25 |
26 | line = view.line(locations[0])
27 |
28 | start = max(line.begin(), rv._output_end)
29 | end = line.end()
30 |
31 | whole_line = view.substr(sublime.Region(start, end))
32 | pos_in_line = locations[0] - start
33 | whole_prefix = whole_line[:pos_in_line]
34 |
35 | completions = repl.autocomplete_completions(
36 | whole_line=whole_line,
37 | pos_in_line=pos_in_line,
38 | prefix=prefix,
39 | whole_prefix=whole_prefix,
40 | locations=locations)
41 | return completions, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS
42 |
--------------------------------------------------------------------------------
/config/Groovy/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "id": "repl_groovy",
13 | "caption": "Groovy",
14 | "mnemonic": "G",
15 | "args": {
16 | "type": "subprocess",
17 | "encoding": "utf8",
18 | "external_id": "groovy",
19 | "cmd": {"linux": ["groovysh", "--terminal=none"],
20 | "osx": ["groovysh", "--terminal=none"],
21 | "windows": ["groovysh.bat", "--terminal=none"]},
22 | "soft_quit": "\nexit\n",
23 | "cwd": "$file_path",
24 | "cmd_postfix": "\n",
25 | "extend_env": {"osx": {"PATH": "{PATH}:/usr/local/bin"},
26 | "linux": {"PATH": "{PATH}:/usr/local/bin"},
27 | "windows": {}},
28 | "suppress_echo": false,
29 | "syntax": "Packages/Groovy/Groovy.tmLanguage"
30 | }
31 | }
32 | ]
33 | }]
34 | }
35 | ]
36 |
--------------------------------------------------------------------------------
/config/OCaml/OCaml (toplevel).tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | OCaml (toplevel)
7 | patterns
8 |
9 |
10 | begin
11 | ^#
12 | end
13 | (;;|^(?=! ))
14 | name
15 | source.ocaml.toplevel.embedded.input
16 | patterns
17 |
18 |
19 | include
20 | source.ocaml
21 |
22 |
23 |
24 |
25 | begin
26 | ^-
27 | end
28 | ^(?=#)
29 | name
30 | source.ocaml.toplevel.embedded.value
31 | patterns
32 |
33 |
34 | include
35 | source.ocaml
36 |
37 |
38 |
39 |
40 | begin
41 | ^!
42 | end
43 | $
44 | name
45 | invalid.ocaml.toplevel.stderr
46 |
47 |
48 | scopeName
49 | source.ocaml.toplevel
50 | uuid
51 | d1a342ce-4108-11e3-b309-1b404228fc7c
52 |
53 |
54 |
--------------------------------------------------------------------------------
/config/Rails/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "Rails",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {
12 | "command": "repl_open",
13 | "caption": "Rails",
14 | "id": "repl_rails",
15 | "external_id":"rails",
16 | "mnemonic": "R",
17 | "args":
18 | {
19 | "type": "subprocess",
20 | "encoding": {"windows": "$win_cmd_encoding",
21 | "linux": "utf-8",
22 | "osx": "utf-8"},
23 | "cmd": { "windows": ["ruby.exe", "${packages}/SublimeREPL/config/Rails/pry_repl.rb", "$editor"],
24 | "linux": ["ruby", "${packages}/SublimeREPL/config/Rails/pry_repl.rb", "$editor"],
25 | "osx": ["ruby", "${packages}/SublimeREPL/config/Rails/pry_repl.rb", "$editor"] },
26 | "env": {},
27 | "soft_quit":"\nexit\n",
28 | "cwd":"$folder",
29 | "cmd_postfix":"\n",
30 | "autocomplete_server": true,
31 | "syntax": "Packages/Ruby/Ruby.tmLanguage"
32 | }
33 | }
34 | ]
35 | }]
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/config/Clojure/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Clojure",
12 | "id": "Clojure",
13 | "children":[
14 | {"command": "repl_open",
15 | "caption": "Clojure",
16 | "id": "repl_clojure",
17 | "args": {
18 | "type": "subprocess",
19 | "encoding": "utf8",
20 | "cmd": {"windows": ["lein.bat", "repl"],
21 | "linux": ["lein", "repl"],
22 | "osx": ["lein", "repl"]},
23 | "soft_quit": "\n(. System exit 0)\n",
24 | "cwd": {"windows":"c:/Clojure",
25 | "linux": "$file_path",
26 | "osx": "$file_path"},
27 | "syntax": "Packages/Clojure/Clojure.tmLanguage",
28 | "external_id": "clojure",
29 | "extend_env": {"INSIDE_EMACS": "1"}
30 | }
31 | },
32 | {"command": "clojure_auto_telnet_repl",
33 | "id": "repl_clojure_telnet",
34 | "caption": "Clojure-Telnet"}]}
35 | ]
36 | }]
37 | }
38 | ]
39 |
--------------------------------------------------------------------------------
/repls/telnet_repl.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2011, Wojciech Bederski (wuub.net)
3 | # All rights reserved.
4 | # See LICENSE.txt for details.
5 |
6 | import telnetlib
7 | from . import repl
8 |
9 | class TelnetRepl(repl.Repl):
10 | TYPE = "telnet"
11 |
12 | def __init__(self, encoding, host="localhost", port=23, **kwds):
13 | """Create new TelnetRepl with the following initial values:
14 | encoding: one of python accepted encoding used to encode commands and decode responses
15 | external_id: external, persisten name of this repl used to find it later
16 | host: telnet host to connect to
17 | port: telnet port to connect to
18 | cmd_postfix: some REPLS require you to end a command with a postfix to begin execution,
19 | think ';' or '.', you can force repl to add it automatically"""
20 | super(TelnetRepl, self).__init__(encoding, **kwds)
21 | self._telnet = telnetlib.Telnet()
22 | #convert to int for user's sake, we don't care if it's an float or string
23 | # as long as it can be turned into an INT
24 | self._telnet.open(host, int(port))
25 | self._alive = True
26 | self._killed = False
27 |
28 | def name(self):
29 | return "%s:%s" % (self._telnet.host, self._telnet.port)
30 |
31 | def is_alive(self):
32 | return self._alive
33 |
34 | def read_bytes(self):
35 | return self._telnet.read_some()
36 |
37 | def write_bytes(self, bytes):
38 | self._telnet.write(bytes)
39 |
40 | def kill(self):
41 | self._killed = True
42 | self._telnet.close()
43 | self._alive = False
44 |
--------------------------------------------------------------------------------
/config/Rails/pry_repl.rb:
--------------------------------------------------------------------------------
1 | # Simply merged `pry_repl.rb` from the Ruby REPL and - https://github.com/doitian/rails-console-pry
2 |
3 | require 'rubygems'
4 | gem 'pry'
5 | require 'pry'
6 | require 'thread'
7 | require 'json'
8 | require 'pry-rails/version'
9 | pry_rails_path = Gem.loaded_specs['pry-rails']
10 |
11 | class PryInput
12 | def readline(prompt)
13 | $stdout.print prompt
14 | $stdout.flush
15 | $stdin.readline
16 | end
17 | end
18 |
19 | class PryOutput
20 | def puts(data="")
21 | $stdout.puts(data.gsub('`', "'"))
22 | $stdout.flush
23 | end
24 | end
25 |
26 | Pry.config.input = PryInput.new()
27 | Pry.config.output = PryOutput.new()
28 | Pry.config.color = false
29 | Pry.config.editor = ARGV[0]
30 | Pry.config.auto_indent = false
31 | Pry.config.correct_indent = false
32 |
33 | port = ENV["SUBLIMEREPL_AC_PORT"].to_i
34 |
35 | completer = Pry::InputCompleter.build_completion_proc(binding)
36 |
37 | def read_netstring(s)
38 | size = 0
39 | while true
40 | ch = s.recvfrom(1)[0]
41 | if ch == ':'
42 | break
43 | end
44 | size = size * 10 + ch.to_i
45 | end
46 | msg = ""
47 | while size != 0
48 | msg += s.recvfrom(size)[0]
49 | size -= msg.length
50 | end
51 | ch = s.recvfrom(1)[0]
52 | return msg
53 | end
54 |
55 | ENV['RAILS_ENV'] = "development"
56 |
57 | APP_PATH = File.expand_path('config/application')
58 | require APP_PATH
59 |
60 | if ::Rails::VERSION::MAJOR >= 3
61 | class ::Rails::Console
62 | end
63 | end
64 |
65 | ARGV.unshift "console"
66 |
67 | $: << File.join(pry_rails_path.full_gem_path, 'lib')
68 | require 'pry-rails'
69 |
70 | require 'rails/commands'
71 |
72 |
--------------------------------------------------------------------------------
/config/R/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"command": "repl_open",
12 | "caption": "R",
13 | "id": "repl_r",
14 | "mnemonic": "R",
15 | "args": {
16 | "type": "subprocess",
17 | "external_id": "r",
18 | "additional_scopes": ["tex.latex.knitr"],
19 | "encoding": {
20 | "windows": "$win_cmd_encoding",
21 | "linux": "utf8",
22 | "osx": "utf8"
23 | },
24 | "soft_quit": "\nquit(save=\"no\")\n",
25 | "cmd": {"linux": ["R", "--interactive", "--no-readline"],
26 | "osx": ["R", "--interactive", "--no-readline"],
27 | "windows": ["Rterm.exe", "--ess", "--encoding=$win_cmd_encoding"]},
28 | "cwd": "$file_path",
29 | "extend_env": {"osx": {"PATH": "{PATH}:/usr/local/bin"},
30 | "linux": {"PATH": "{PATH}:/usr/local/bin"},
31 | "windows": {}},
32 | "cmd_postfix": "\n",
33 | "suppress_echo": {"osx": true,
34 | "linux": true,
35 | "windows": false},
36 | "syntax": "Packages/R/R Console.tmLanguage"
37 | }
38 | }
39 | ]
40 | }]
41 | }
42 | ]
43 |
--------------------------------------------------------------------------------
/config/CommonLisp/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "SublimeREPL: Clozure CL",
4 | "command": "run_existing_window_command", "args":
5 | {
6 | "id": "repl_ccl",
7 | "file": "config/CommonLisp/Main.sublime-menu"
8 | }
9 | },
10 | {
11 | "caption": "SublimeREPL: SBCL",
12 | "command": "run_existing_window_command", "args":
13 | {
14 | "id": "repl_sbcl",
15 | "file": "config/CommonLisp/Main.sublime-menu"
16 | }
17 | },
18 | {
19 | "caption": "SublimeREPL: GNU Clisp",
20 | "command": "run_existing_window_command", "args":
21 | {
22 | "id": "repl_clisp",
23 | "file": "config/CommonLisp/Main.sublime-menu"
24 | }
25 | },
26 | {
27 | "caption": "SublimeREPL: Allegro CL",
28 | "command": "run_existing_window_command", "args":
29 | {
30 | "id": "repl_allegro",
31 | "file": "config/CommonLisp/Main.sublime-menu"
32 | }
33 | },
34 | {
35 | "caption": "SublimeREPL: ABCL",
36 | "command": "run_existing_window_command", "args":
37 | {
38 | "id": "repl_abcl",
39 | "file": "config/CommonLisp/Main.sublime-menu"
40 | }
41 | },
42 | {
43 | "caption": "SublimeREPL: CMUCL",
44 | "command": "run_existing_window_command", "args":
45 | {
46 | "id": "repl_cmucl",
47 | "file": "config/CommonLisp/Main.sublime-menu"
48 | }
49 | },
50 | {
51 | "caption": "SublimeREPL: ECL",
52 | "command": "run_existing_window_command", "args":
53 | {
54 | "id": "repl_ecl",
55 | "file": "config/CommonLisp/Main.sublime-menu"
56 | }
57 | }
58 | ]
59 |
--------------------------------------------------------------------------------
/config/Ruby/pry_repl.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | gem 'pry'
3 | require 'pry'
4 | require 'socket'
5 | require 'thread'
6 | require 'json'
7 |
8 | include Socket::Constants
9 |
10 | class PryInput
11 | def readline(prompt)
12 | $stdout.print prompt
13 | $stdout.flush
14 | $stdin.readline
15 | end
16 | end
17 |
18 | class PryOutput
19 | def puts(data="")
20 | $stdout.puts(data.gsub('`', "'"))
21 | $stdout.flush
22 | end
23 | end
24 |
25 | Pry.config.input = PryInput.new()
26 | Pry.config.output = PryOutput.new()
27 | Pry.config.color = false
28 | Pry.config.editor = ARGV[0]
29 | Pry.config.auto_indent = false
30 | Pry.config.correct_indent = false
31 |
32 | port = ENV["SUBLIMEREPL_AC_PORT"].to_i
33 |
34 | socket = Socket.new(AF_INET, SOCK_STREAM, 0)
35 | sockaddr = Socket.pack_sockaddr_in(port, '127.0.0.1')
36 | socket.connect(sockaddr)
37 | completer = Pry::InputCompleter.build_completion_proc(binding)
38 |
39 | def read_netstring(s)
40 | size = 0
41 | while true
42 | ch = s.recvfrom(1)[0]
43 | if ch == ':'
44 | break
45 | end
46 | size = size * 10 + ch.to_i
47 | end
48 | msg = ""
49 | while size != 0
50 | msg += s.recvfrom(size)[0]
51 | size -= msg.length
52 | end
53 | ch = s.recvfrom(1)[0]
54 | return msg
55 | end
56 |
57 | # Thread.abort_on_exception = true
58 | t1 = Thread.new do
59 | while true
60 | data = read_netstring(socket)
61 | req = JSON.parse(data)
62 | line = req["line"]
63 | completions = completer.call(req["line"])
64 | response = [line, completions]
65 | response_msg = JSON.dump(response)
66 | payload = response_msg.length.to_s + ":" + response_msg + ","
67 | socket.write(payload)
68 | end
69 | end
70 |
71 |
72 | Pry.start self
73 |
--------------------------------------------------------------------------------
/repls/autocomplete_server.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import json
4 | import socket
5 | import threading
6 | import sublime
7 |
8 | def read_netstring(s):
9 | size = 0
10 | while True:
11 | byte = s.recv(1)
12 | if byte == b':':
13 | break
14 | size = size * 10 + int(byte)
15 | msg = b""
16 | while size != 0:
17 | msg += s.recv(size)
18 | size -= len(msg)
19 | byte = s.recv(1)
20 | assert byte == b','
21 | return msg.decode("utf-8")
22 |
23 | def send_netstring(s, msg):
24 | payload = "".join([str(len(msg)), ':', msg, ',']).encode("utf-8")
25 | s.sendall(payload)
26 |
27 |
28 | class AutocompleteServer(object):
29 | def __init__(self, repl, server_ip="127.0.0.1"):
30 | self._repl = repl
31 | self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
32 | self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
33 | self._cli_sock = None
34 | self._server_ip = server_ip
35 |
36 | def start(self):
37 | self._sock.bind((self._server_ip, 0))
38 | threading.Thread(target=self._wait).start()
39 |
40 | def _wait(self):
41 | self._sock.listen(1)
42 | s, address = self._sock.accept()
43 | self._cli_sock = s
44 |
45 | def port(self):
46 | return self._sock.getsockname()[1]
47 |
48 | def connected(self):
49 | return bool(self._cli_sock)
50 |
51 | def complete(self, whole_line, pos_in_line, prefix, whole_prefix, locations):
52 | req = json.dumps({"text": "", "line": whole_line, "cursor_pos": pos_in_line})
53 | send_netstring(self._cli_sock, req)
54 | self._cli_sock.settimeout(4)
55 | msg = read_netstring(self._cli_sock)
56 | self._cli_sock.settimeout(None)
57 | res = json.loads(msg)
58 | if not res:
59 | return []
60 | return [(x, x) for x in res[1]]
61 |
--------------------------------------------------------------------------------
/run_existing_command.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
2 |
3 | import os
4 | import os.path
5 | import sys
6 | import json
7 | import sublime
8 | import sublime_plugin
9 |
10 | SUBLIMEREPL_DIR = None
11 | SUBLIMEREPL_USER_DIR = None
12 |
13 | def plugin_loaded():
14 | global SUBLIMEREPL_DIR
15 | global SUBLIMEREPL_USER_DIR
16 | SUBLIMEREPL_DIR = "Packages/SublimeREPL"
17 | SUBLIMEREPL_USER_DIR = os.path.join(sublime.packages_path(), "User", "SublimeREPL")
18 |
19 | PY2 = False
20 | if sys.version_info[0] == 2:
21 | SUBLIMEREPL_DIR = os.getcwdu()
22 | SUBLIMEREPL_USER_DIR = os.path.join(sublime.packages_path(), "User", "SublimeREPL")
23 | PY2 = True
24 |
25 | # yes, CommandCommmand :)
26 | class RunExistingWindowCommandCommand(sublime_plugin.WindowCommand):
27 | def run(self, id, file):
28 | """Find and run existing command with id in specified file.
29 | SUBLIMEREPL_USER_DIR is consulted first, and then SUBLIMEREPL_DIR"""
30 | for prefix in (SUBLIMEREPL_USER_DIR, SUBLIMEREPL_DIR):
31 | path = os.path.join(prefix, file)
32 | json_cmd = self._find_cmd(id, path)
33 | if json_cmd:
34 | break
35 | if not json_cmd:
36 | return
37 | args = json_cmd["args"] if "args" in json_cmd else None
38 | self.window.run_command(json_cmd["command"], args)
39 |
40 | def _find_cmd(self, id, file):
41 | return self._find_cmd_in_file(id, file)
42 |
43 | def _find_cmd_in_file(self, id, file):
44 | try:
45 | if PY2 or os.path.isfile(file):
46 | with open(file) as f:
47 | bytes = f.read()
48 | else:
49 | bytes = sublime.load_resource(file)
50 | except (IOError, ValueError):
51 | return None
52 | else:
53 | data = json.loads(bytes)
54 | return self._find_cmd_in_json(id, data)
55 |
56 | def _find_cmd_in_json(self, id, json_object):
57 | if isinstance(json_object, list):
58 | for elem in json_object:
59 | cmd = self._find_cmd_in_json(id, elem)
60 | if cmd:
61 | return cmd
62 | elif isinstance(json_object, dict):
63 | if "id" in json_object and json_object["id"] == id:
64 | return json_object
65 | elif "children" in json_object:
66 | return self._find_cmd_in_json(id, json_object["children"])
67 | return None
--------------------------------------------------------------------------------
/config/ClojureScript/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "ClojureScript",
12 | "id": "ClojureScript",
13 | "children":[
14 | {"command": "repl_open",
15 | "caption": "ClojureScript Browser REPL",
16 | "id": "repl_clojurescript_browser",
17 | "args": {
18 | "type": "subprocess",
19 | "encoding": "utf8",
20 | "cmd": {"windows": ["lein.bat", "trampoline", "cljsbuild", "repl-listen"],
21 | "linux": ["lein", "trampoline", "cljsbuild", "repl-listen"],
22 | "osx": ["lein", "trampoline", "cljsbuild", "repl-listen"]},
23 | "soft_quit": "\n(. System exit 0)\n",
24 | "cwd": {"windows":"c:/Clojure",
25 | "linux": "$file_path",
26 | "osx": "$file_path"},
27 | "syntax": "Packages/Clojure/Clojure.tmLanguage",
28 | "external_id": "clojurescript",
29 | "extend_env": {"INSIDE_EMACS": "1"}
30 | }
31 | },
32 | {"command": "repl_open",
33 | "caption": "ClojureScript",
34 | "id": "repl_clojurescript",
35 | "args": {
36 | "type": "subprocess",
37 | "encoding": "utf8",
38 | "cmd": {"windows": ["lein.bat", "trampoline", "cljsbuild", "repl-rhino"],
39 | "linux": ["lein", "trampoline", "cljsbuild", "repl-rhino"],
40 | "osx": ["lein", "trampoline", "cljsbuild", "repl-rhino"]},
41 | "soft_quit": "\n(. System exit 0)\n",
42 | "cwd": {"windows":"c:/Clojure",
43 | "linux": "$file_path",
44 | "osx": "$file_path"},
45 | "syntax": "Packages/Clojure/Clojure.tmLanguage",
46 | "external_id": "clojurescript",
47 | "extend_env": {"INSIDE_EMACS": "1"}
48 | }
49 | }
50 | ]}
51 | ]
52 | }]
53 | }
54 | ]
55 |
--------------------------------------------------------------------------------
/config/Scala/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Scala",
12 | "id": "Scala",
13 |
14 | "children":[
15 | {"command": "repl_open",
16 | "caption": "scala REPL",
17 | "id": "repl_scala",
18 | "mnemonic": "s",
19 | "args": {
20 | "type": "subprocess",
21 | "encoding": "utf8",
22 | "external_id": "scala",
23 | "cmd": {"linux": ["scala"],
24 | "osx": ["scala"],
25 | "windows": ["scala.bat", "-i"]},
26 | "soft_quit": "\nexit\n",
27 | "cwd": "$file_path",
28 | "cmd_postfix": "\n",
29 | "extend_env": {"osx": {"EMACS": "1", "PATH": "{PATH}:/usr/local/bin"},
30 | "linux": {"EMACS": "1", "PATH": "{PATH}:/usr/local/bin"},
31 | "windows": {"EMACS": "1"}},
32 | "suppress_echo": false,
33 | "syntax": "Packages/Scala/Scala.tmLanguage"
34 | }
35 | },
36 | {"command": "repl_open",
37 | "caption": "SBT for opened folder",
38 | "id": "repl_sbt",
39 | "mnemonic": "B",
40 | "args": {
41 | "type": "subprocess",
42 | "encoding": "utf8",
43 | "external_id": "scala",
44 | "cmd": {"linux": ["sbt"],
45 | "osx": ["sbt"],
46 | "windows": ["sbt"]},
47 | "soft_quit": "\nexit\n",
48 | "cwd": "$folder",
49 | "cmd_postfix": "\n",
50 | "extend_env": {"osx": {"EMACS": "1", "PATH": "{PATH}:/usr/local/bin"},
51 | "linux": {"EMACS": "1", "PATH": "{PATH}:/usr/local/bin"},
52 | "windows": {"EMACS": "1"}},
53 | "suppress_echo": false,
54 | "syntax": "Packages/Scala/Scala.tmLanguage"
55 | }
56 | }
57 | ]}
58 | ]
59 | }]
60 | }
61 | ]
62 |
--------------------------------------------------------------------------------
/config/OCaml/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id":"tools",
4 | "children":[
5 | {
6 | "caption":"SublimeREPL",
7 | "mnemonic":"R",
8 | "id":"SublimeREPL",
9 | "children":[
10 | {
11 | "caption":"OCaml",
12 | "children":[
13 | {
14 | "command":"repl_open",
15 | "caption":"OCaml toplevel",
16 | "id":"repl_ocaml",
17 | "mnemonic":"t",
18 | "args":{
19 | "type":"subprocess",
20 | "external_id":"ocaml",
21 | "encoding":"utf8",
22 | "cmd":{
23 | "windows":[
24 | "ocaml.exe"
25 | ],
26 | "linux":[
27 | "ocaml"
28 | ],
29 | "osx":[
30 | "ocaml"
31 | ]
32 | },
33 | "soft_quit":"\n#quit;;\n",
34 | "cwd":"$file_path",
35 | "cmd_postfix":";;\n",
36 | "autocomplete_server": false,
37 | "syntax":"Packages/SublimeREPL/config/OCaml/OCaml (toplevel).tmLanguage"
38 | }
39 | },
40 | {
41 | "command":"repl_open",
42 | "caption":"OCaml utop",
43 | "id":"repl_ocaml_utop",
44 | "mnemonic":"u",
45 | "args":{
46 | "type":"sublime_utop",
47 | "external_id":"ocaml",
48 | "encoding":"utf8",
49 | "cmd":{
50 | "windows":[
51 | "utop.exe", "-emacs"
52 | ],
53 | "linux":[
54 | "utop", "-emacs"
55 | ],
56 | "osx":[
57 | "utop", "-emacs"
58 | ]
59 | },
60 | "soft_quit":"\n#quit;;\n",
61 | "cwd":"$file_path",
62 | "cmd_postfix":"",
63 | "extend_env": {
64 | "OCAML_TOPLEVEL_PATH": "{HOME}/.opam/system/lib/toplevel",
65 | "CAML_LD_LIBRARY_PATH": "{HOME}/.opam/system/lib/stublibs:/usr/lib/ocaml/stublibs",
66 | "PATH": "{PATH}:{HOME}/.opam/system/bin"
67 | },
68 | "autocomplete_server": false,
69 | "syntax":"Packages/SublimeREPL/config/OCaml/OCaml (toplevel).tmLanguage"
70 | }
71 | }
72 | ]
73 | }
74 | ]
75 | }
76 | ]
77 | }
78 | ]
79 |
--------------------------------------------------------------------------------
/config/Ruby/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id":"tools",
4 | "children":[
5 | {
6 | "caption":"SublimeREPL",
7 | "mnemonic":"R",
8 | "id":"SublimeREPL",
9 | "children":[
10 | {
11 | "caption":"Ruby",
12 | "children":[
13 | {
14 | "command":"repl_open",
15 | "caption":"Ruby",
16 | "id":"repl_ruby",
17 | "mnemonic":"R",
18 | "args":{
19 | "type":"subprocess",
20 | "external_id":"ruby",
21 | "encoding":"utf8",
22 | "cmd":{
23 | "windows":[
24 | "ruby.exe",
25 | "${packages}/SublimeREPL/config/Ruby/pry_repl.rb",
26 | "$editor"
27 | ],
28 | "linux":[
29 | "ruby",
30 | "${packages}/SublimeREPL/config/Ruby/pry_repl.rb",
31 | "$editor"
32 | ],
33 | "osx":[
34 | "ruby",
35 | "${packages}/SublimeREPL/config/Ruby/pry_repl.rb",
36 | "$editor"
37 | ]
38 | },
39 | "soft_quit":"\nexit\n",
40 | "cwd":"$file_path",
41 | "cmd_postfix":"\n",
42 | "autocomplete_server": true,
43 | "syntax":"Packages/Ruby/Ruby.tmLanguage"
44 | }
45 | },
46 | {
47 | "command":"repl_open",
48 | "caption":"Ruby - IRB (deprecated)",
49 | "id":"repl_ruby_irb",
50 | "mnemonic":"I",
51 | "args":{
52 | "type":"subprocess",
53 | "external_id":"ruby",
54 | "encoding":"utf8",
55 | "cmd":{
56 | "windows":[
57 | "irb.bat",
58 | "--noreadline",
59 | "--inf-ruby-mode"
60 | ],
61 | "linux":[
62 | "irb",
63 | "--noreadline",
64 | "--inf-ruby-mode"
65 | ],
66 | "osx":[
67 | "irb",
68 | "--noreadline",
69 | "--inf-ruby-mode"
70 | ]
71 | },
72 | "soft_quit":"\nexit\n",
73 | "cwd":"$file_path",
74 | "cmd_postfix":"\n",
75 | "suppress_echo":true,
76 | "syntax":"Packages/Ruby/Ruby.tmLanguage"
77 | }
78 | }
79 | ]
80 | }
81 | ]
82 | }
83 | ]
84 | }
85 | ]
86 |
--------------------------------------------------------------------------------
/repls/sublimepython_repl.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import code
3 | import contextlib
4 | from .repl import Repl
5 | try:
6 | from queue import Queue
7 | except ImportError:
8 | from Queue import Queue
9 | import sys
10 | import threading
11 | import sublime
12 |
13 |
14 | class QueueOut(object):
15 | def __init__(self, queue):
16 | self.queue = queue
17 |
18 | def write(self, data):
19 | self.queue.put(data)
20 |
21 |
22 | @contextlib.contextmanager
23 | def redirect_stdio(queue):
24 | orig = (sys.stdout, sys.stderr)
25 | sys.stdout = sys.stderr = QueueOut(queue)
26 | yield
27 | (sys.stdout, sys.stderr) = orig
28 |
29 |
30 | class SublimeLocals(dict):
31 | def __init__(self, *args, **kwds):
32 | import pydoc
33 | super(SublimeLocals, self).__init__(*args, **kwds)
34 | self['sublime'] = sublime
35 | self['__name__'] = "__main__"
36 | self['view'] = None
37 | self['window'] = None
38 | self['help'] = pydoc.help
39 |
40 | def __getitem__(self, key):
41 | if key == 'window':
42 | return sublime.active_window()
43 | if key == 'view':
44 | return sublime.active_window().active_view()
45 | return super(SublimeLocals, self).__getitem__(key)
46 |
47 |
48 | class InterceptingConsole(code.InteractiveConsole):
49 | PS1 = ">>> "
50 | PS2 = "... "
51 |
52 | def __init__(self, encoding):
53 | code.InteractiveConsole.__init__(self, locals=SublimeLocals())
54 | self.input = Queue()
55 | self.output = Queue()
56 | self.output.put(self.PS1)
57 | self._encoding = encoding
58 |
59 | def write(self, data):
60 | self.output.put(data)
61 |
62 | def push(self, line):
63 | with redirect_stdio(self.output):
64 | more = code.InteractiveConsole.push(self, line.decode(self._encoding))
65 | self.output.put(self.PS2 if more else self.PS1)
66 | return more
67 |
68 | def run(self):
69 | while True:
70 | line = self.input.get()
71 | if line is None:
72 | break
73 | self.push(line)
74 |
75 |
76 | class SublimePythonRepl(Repl):
77 | TYPE = "sublime_python"
78 |
79 | def __init__(self, encoding):
80 | super(SublimePythonRepl, self).__init__(encoding, "python", "\n", False)
81 | self._console = InterceptingConsole(encoding)
82 | self._thread = threading.Thread(target=self._console.run)
83 | self._thread.start()
84 |
85 | def name(self):
86 | return "sublime"
87 |
88 | def is_alive(self):
89 | return True
90 |
91 | def write_bytes(self, bytes):
92 | self._console.input.put(bytes)
93 |
94 | def read_bytes(self):
95 | return self._console.output.get().encode(self._encoding)
96 |
97 | def kill(self):
98 | self._console.input.put(None)
99 |
--------------------------------------------------------------------------------
/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Eval in REPL",
12 | "children":
13 | [
14 | {"caption": "Selection", "command": "repl_transfer_current", "args": {"scope": "selection"}},
15 | {"caption": "File", "command": "repl_transfer_current", "args": {"scope": "file"}},
16 | {"caption": "Lines", "command": "repl_transfer_current", "args": {"scope": "lines"}},
17 | {"caption": "Block", "command": "repl_transfer_current", "args": {"scope": "block"}}
18 | ]},
19 | {"caption": "Transfer to REPL",
20 | "children":
21 | [
22 | {"caption": "Selection", "command": "repl_transfer_current", "args": {"scope": "selection", "action":"view_write"}},
23 | {"caption": "File", "command": "repl_transfer_current", "args": {"scope": "file", "action":"view_write"}},
24 | {"caption": "Lines", "command": "repl_transfer_current", "args": {"scope": "lines", "action":"view_write"}},
25 | {"caption": "Block", "command": "repl_transfer_current", "args": {"scope": "block", "action":"view_write"}}
26 | ]
27 | },
28 | { "caption": "-" }
29 | ]
30 | }]
31 | },
32 |
33 | {
34 | "caption": "Preferences",
35 | "mnemonic": "n",
36 | "id": "preferences",
37 | "children":
38 | [
39 | {
40 | "caption": "Package Settings",
41 | "mnemonic": "P",
42 | "id": "package-settings",
43 | "children":
44 | [
45 | {
46 | "caption": "SublimeREPL",
47 | "children":
48 | [
49 | {
50 | "command": "open_file", "args":
51 | {
52 | "file": "${packages}/SublimeREPL/SublimeREPL.sublime-settings"
53 | },
54 | "caption": "Settings – Default"
55 | },
56 | {
57 | "command": "open_file", "args":
58 | {
59 | "file": "${packages}/User/SublimeREPL.sublime-settings"
60 | },
61 | "caption": "Settings – User"
62 | },
63 | { "caption": "-" }
64 | ]
65 | }
66 | ]
67 | }
68 | ]
69 | }
70 | ]
71 |
--------------------------------------------------------------------------------
/config/Scheme/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Scheme",
12 | "id": "Scheme",
13 |
14 | "children":[
15 | {"command": "repl_open",
16 | "caption": "Scheme",
17 | "id": "repl_scheme",
18 | "mnemonic": "S",
19 | "args": {
20 | "type": "subprocess",
21 | "encoding": "utf8",
22 | "external_id": "scheme",
23 | "cmd": {"linux": ["scheme"],
24 | "osx": ["scheme"],
25 | "windows": ["scheme"]},
26 | "soft_quit": "\nexit\n",
27 | "cwd": "$folder",
28 | "cmd_postfix": "\n",
29 | "extend_env": {"INSIDE_EMACS": "1"},
30 | "syntax": "Packages/sublime-scheme-syntax/Scheme.tmLanguage"
31 | }
32 | },
33 | {"command": "repl_open",
34 | "caption": "Gauche",
35 | "id": "repl_gauche",
36 | "mnemonic": "G",
37 | "args": {
38 | "type": "subprocess",
39 | "encoding": "utf8",
40 | "external_id": "gauche",
41 | "cmd": {"linux": ["gosh", "-i"],
42 | "osx": ["gosh", "-i"],
43 | "windows": ["gosh", "-i"]},
44 | "soft_quit": "\n(exit)\n",
45 | "cwd": "$folder",
46 | "cmd_postfix": "\n",
47 | "extend_env": {"INSIDE_EMACS": "1"},
48 | "syntax": "Packages/Gauche/Gauche.tmLanguage"
49 | }
50 | },
51 | {"command": "repl_open",
52 | "caption": "Petite Chez Scheme",
53 | "id": "repl_petite",
54 | "mnemonic": "P",
55 | "args": {
56 | "type": "subprocess",
57 | "encoding": "utf8",
58 | "external_id": "petite",
59 | "cmd": {"linux": ["petite"],
60 | "osx": ["petite"],
61 | "windows": ["petite"]},
62 | "soft_quit": "\n(exit)\n",
63 | "cwd": "$folder",
64 | "cmd_postfix": "\n",
65 | "extend_env": {"INSIDE_EMACS": "1"},
66 | "syntax": "Packages/sublime-scheme-syntax/Scheme.tmLanguage"
67 | }
68 | }
69 | ]}
70 | ]
71 | }]
72 | }
73 | ]
74 |
--------------------------------------------------------------------------------
/repls/powershell_repl.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2011, Wojciech Bederski (wuub.net)
3 | # All rights reserved.
4 | # See LICENSE.txt for details.
5 | import os
6 | import re
7 | from . import subprocess_repl
8 |
9 | # PowerShell in interactive mode shows no prompt, so we must hold it by hand.
10 | # Every command prepended with other command, which will output only one character ('.')
11 | # When user command leads to no output (for example, 'cd ..'), we get only this character,
12 | # and then we send command to show prompt explicitly.
13 | # No output at all means, that PowerShell needs more input (multiline mode).
14 | # In this case we proceeds sending user input without modifications.
15 |
16 | class PowershellRepl(subprocess_repl.SubprocessRepl):
17 | TYPE = "powershell"
18 | PREPENDER = b"."
19 |
20 | def __init__(self, encoding, **kwds):
21 | if not encoding:
22 | # Detect encoding
23 | chcp = os.popen('chcp')
24 | chcp_encoding = re.match(r'[^\d]+(\d+)', chcp.read())
25 | if not chcp_encoding:
26 | raise LookupError("Can't detect encoding from chcp")
27 | encoding = "cp" + chcp_encoding.groups()[0]
28 | print(encoding)
29 |
30 | super(PowershellRepl, self).__init__(encoding, **kwds)
31 |
32 | # Using this to detect whether PowerShell returns some output or it needs more input
33 | # PowerShell in interactive mode doesn't show prompt, so we must hold it by hand
34 | # It's a hack and, for example, we can send 'Write-Host "" -NoNewLine' with no output, but in outhr cases it may work well
35 | self.got_output = True
36 | self.multiline = False
37 |
38 | self.prompt()
39 |
40 | def read_bytes(self):
41 | # this is windows specific problem, that you cannot tell if there
42 | # are more bytes ready, so we read only 1 at a times
43 |
44 | result = super(PowershellRepl, self).read_bytes()
45 |
46 | # Consumes output (it must be equal to PREPENDER)
47 | if result and not self.got_output:
48 | self.got_output = True
49 | self.multiline = False
50 | self.prompt()
51 | # Don't return PREPENDER, read another input
52 | return self.read_bytes()
53 |
54 | return result
55 |
56 | def write_bytes(self, bytes):
57 | # Drop flag on new input
58 | self.got_output = False
59 | if not self.multiline:
60 | # Turn multiline mode on, it will be turned off, when PowerShell returns some output
61 | self.multiline = True
62 | self.prepend()
63 | self.do_write(bytes)
64 |
65 | def do_write(self, bytes):
66 | super(PowershellRepl, self).write_bytes(bytes)
67 |
68 | def prompt(self):
69 | """ Sends command to get prompt """
70 | self.do_write(b'Write-Host ("PS " + (gl).Path + "> ") -NoNewline\n')
71 |
72 | def prepend(self):
73 | """ Command to prepend every output with special mark to detect multiline mode """
74 | self.do_write(b'Write-Host "' + PowershellRepl.PREPENDER + b'" -NoNewLine; ')
75 |
--------------------------------------------------------------------------------
/messages/2.0.0.txt:
--------------------------------------------------------------------------------
1 | Welcome to SublimeREPL 2.0.0
2 | ============================
3 |
4 | This is the first, official Sublime Text 3 and Sublime Text 2
5 | compatible release. It's been in the works for over 5 months.
6 |
7 | First the bad news:
8 | - during migration persistent history database was changed from
9 | buzhug to PyDBLite. This means you **will have to rebuild** your history.
10 | - Testing release on 6 separate setups (Linux, OSX, Windows with ST2 & ST3)
11 | is becoming a bit time consuming. Recently I test mostly on Linux with
12 | ST3 and occasionally on Windows with ST3 & ST2.
13 | I expect some early bugs, and **count on you** to let me know if something
14 | out of ordinary is happening. Create github issue, send me an email
15 | (github at wuub.net) or reach me on twitter @wuub :)
16 |
17 |
18 | Now the good news. Lots, and I mean LOTS of issues were closed,
19 | in those 5 months. Many of them directly driven by your input.
20 | Here's a condensed changelog, if you want to learn more
21 | feel free to visit
22 | - https://github.com/wuub/SublimeREPL/issues
23 |
24 |
25 | - NEW: Compatibility with Sublime Text 3 and Sublime Text 2 with single codebase
26 | - NEW: documentation improvements
27 | - NEW: 'Restart' command in context menu (even with ghost views after full ST restart)
28 | - NEW: option to open REPLs in next view group (e.g. side-by-side)
29 | - NEW: add option to show evaluated code (#106 and #84)
30 | - BUGFIX: huge output will no longer cause Sublime to become unresponsive (#23... wow :))
31 | - BUGFIX: closing bracket are now removed automatically (ST3 only, #182)
32 | - NEW: hanlde cases when external_id differs from source.x (think: source.lisp -> scheme repl) (#161, #165 and #167)w
33 | - NEW: [Python] iPython on Windows
34 | - NEW: [Python] automatically remove "#! coding: ..." comments from evaluated code (#187)
35 | - NEW: [Python] iPython plot() support (qt, wx, *not* inline!)
36 | - BUGFIX: [Python] fix pager in IPython (#170)
37 | - BUGFIX: [Python] ipython pager broken on windows (#141)
38 |
39 | - NEW: [Ruby] Pry autocomplete support
40 | - BUGFIX: [Ruby] REPL does not eval at top level (#194)
41 |
42 | - NEW: [Haskell] automatic let binding injection for top level functions
43 | - NEW: [Haskell] let now support top level functions with any kind of parameterization
44 | - BUGFIX: [Haskell] typo in SublimeiHaskellRepl.write(), Code called wrong superclass
45 | - NEW: [Haskell] cabal/cabal-dev depending on SublimeHaskell settings
46 |
47 | - NEW: ClojureScript REPLs
48 | - NEW: Rails REPL
49 | - NEW: Knitr support in R REPL (#165)
50 | - NEW: Maxima REPL
51 | - NEW: Racket REPL
52 | - NEW: Petite Chez Scheme REPL
53 | - REMOVED: Execnet REPL (for now, waiting for community input, anyone uses this?)
54 |
55 | - NEW: change persistent history db from buzhug to PyDbLite (py3)
56 | - BUGFIX: repl could become unresponsive after code evaluation (#159)
57 | - BUGFIX: traceback in is_visible() on context menu
58 | - BUGFIX: AttributeError in update_view_loop
59 | - BUGFIX: fix enter handling with "auto_complete_commit_on_tab": true
60 | - BUGFIX: [F#] The mono command for F# interactive is fsharpi.
61 | - BUGFIX [PowerShell] update pattern for chcp_encoding detection
--------------------------------------------------------------------------------
/repls/execnet_repl.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | from . import repl
3 | from queue import Queue
4 | import sys
5 | import execnet
6 |
7 | REMOTE_CODE = """
8 | from __future__ import with_statement
9 | from __future__ import division
10 | from __future__ import absolute_import
11 | #if '{activate_file}':
12 | # execfile('{activate_file}', dict(__file__='{activate_file}'))
13 |
14 | import code
15 | import sys
16 | import time
17 | import contextlib
18 | import threading
19 | try:
20 | from Queue import Queue
21 | except ImportError:
22 | from queue import Queue # py3
23 |
24 | class ChannelOut(object):
25 | def write(self, data):
26 | channel.send(data)
27 | def flush(self):
28 | pass
29 |
30 | @contextlib.contextmanager
31 | def redirect_stdio():
32 | orig = (sys.stdout, sys.stderr)
33 | sys.stdout = sys.stderr = ChannelOut()
34 | yield
35 | (sys.stdout, sys.stderr) = orig
36 |
37 | class InterceptingConsole(code.InteractiveConsole):
38 | PS1 = "{ps1}"
39 | PS2 = "... "
40 | def __init__(self):
41 | code.InteractiveConsole.__init__(self)
42 | self.input = Queue()
43 | self.output = channel
44 | self.output.send(self.PS1)
45 |
46 | def write(self, data):
47 | self.output.send(data)
48 |
49 | def push(self, line):
50 | with redirect_stdio():
51 | more = code.InteractiveConsole.push(self, line)
52 | self.output.send(self.PS2 if more else self.PS1)
53 | return more
54 |
55 | def run(self):
56 | while True:
57 | line = self.input.get()
58 | if line is None:
59 | break
60 | self.push(line)
61 |
62 |
63 | ic = InterceptingConsole()
64 | _thread = threading.Thread(target=ic.run)
65 | _thread.start()
66 |
67 | channel.setcallback(ic.input.put, endmarker=None)
68 |
69 | while not channel.isclosed():
70 | time.sleep(1.0)
71 | """
72 |
73 |
74 | class ExecnetRepl(repl.Repl):
75 | TYPE = "execnet_repl"
76 |
77 | def __init__(self, encoding, connection_string=None, activate_file="", ps1=">>> "):
78 | super(ExecnetRepl, self).__init__(encoding, "python", "\n", False)
79 | self._connections_string = connection_string
80 | self._ps1 = ps1
81 | self._gw = execnet.makegateway(connection_string)
82 | remote_code = REMOTE_CODE.format(ps1=ps1, activate_file=activate_file)
83 | self._channel = self._gw.remote_exec(remote_code)
84 | self.output = Queue()
85 | self._channel.setcallback(self.output.put, endmarker=None)
86 | self._alive = True
87 | self._killed = False
88 |
89 | def name(self):
90 | return "execnet " + self._ps1.split()[0]
91 |
92 | def is_alive(self):
93 | return self._alive
94 |
95 | def write_bytes(self, bytes):
96 | if self._channel.isclosed():
97 | self._alive = False
98 | else:
99 | self._channel.send(bytes)
100 |
101 | def read_bytes(self):
102 | bytes = self.output.get()
103 | if bytes is None:
104 | self._gw.exit()
105 | else:
106 | return bytes
107 |
108 | def kill(self):
109 | self._killed = True
110 | self._channel.close()
111 | self._gw.exit()
112 |
--------------------------------------------------------------------------------
/config/Python/ipy_repl.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import json
4 | import socket
5 | import threading
6 |
7 | activate_this = os.environ.get("SUBLIMEREPL_ACTIVATE_THIS", None)
8 |
9 | # turn off pager
10 | os.environ['TERM'] = 'emacs'
11 |
12 | if activate_this:
13 | with open(activate_this, "r") as f:
14 | exec(f.read(), {"__file__": activate_this})
15 |
16 | try:
17 | import IPython
18 | IPYTHON = True
19 | except ImportError:
20 | IPYTHON = False
21 |
22 | if not IPYTHON:
23 | # for virtualenvs w/o IPython
24 | import code
25 | code.InteractiveConsole().interact()
26 |
27 | from IPython.config.loader import Config
28 |
29 | editor = "subl -w"
30 |
31 | cfg = Config()
32 | cfg.InteractiveShell.use_readline = False
33 | cfg.InteractiveShell.autoindent = False
34 | cfg.InteractiveShell.colors = "NoColor"
35 | cfg.InteractiveShell.editor = os.environ.get("SUBLIMEREPL_EDITOR", editor)
36 |
37 | try:
38 | # IPython 1.0.0
39 | from IPython.terminal.console.app import ZMQTerminalIPythonApp
40 |
41 | def kernel_client(zmq_shell):
42 | return zmq_shell.kernel_client
43 | except ImportError:
44 | # Older IPythons
45 | from IPython.frontend.terminal.console.app import ZMQTerminalIPythonApp
46 |
47 | def kernel_client(zmq_shell):
48 | return zmq_shell.kernel_manager
49 |
50 |
51 | embedded_shell = ZMQTerminalIPythonApp(config=cfg, user_ns={})
52 | embedded_shell.initialize()
53 |
54 | if os.name == "nt":
55 | # OMG what a fugly hack
56 | import IPython.utils.io as io
57 | io.stdout = io.IOStream(sys.__stdout__, fallback=io.devnull)
58 | io.stderr = io.IOStream(sys.__stderr__, fallback=io.devnull)
59 | embedded_shell.shell.show_banner() # ... my eyes, oh my eyes..
60 |
61 |
62 | ac_port = int(os.environ.get("SUBLIMEREPL_AC_PORT", "0"))
63 | ac_ip = os.environ.get("SUBLIMEREPL_AC_IP", "127.0.0.1")
64 | if ac_port:
65 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
66 | s.connect((ac_ip, ac_port))
67 |
68 |
69 | def read_netstring(s):
70 | size = 0
71 | while True:
72 | ch = s.recv(1)
73 | if ch == b':':
74 | break
75 | size = size * 10 + int(ch)
76 | msg = b""
77 | while size != 0:
78 | msg += s.recv(size)
79 | size -= len(msg)
80 | ch = s.recv(1)
81 | assert ch == b','
82 | return msg
83 |
84 |
85 | def send_netstring(sock, msg):
86 | payload = b"".join([str(len(msg)).encode("ascii"), b':', msg.encode("utf-8"), b','])
87 | sock.sendall(payload)
88 |
89 |
90 | def complete(zmq_shell, req):
91 | kc = kernel_client(zmq_shell)
92 | msg_id = kc.shell_channel.complete(**req)
93 | msg = kc.shell_channel.get_msg(timeout=10)
94 | if msg['parent_header']['msg_id'] == msg_id:
95 | return msg["content"]["matches"]
96 | return []
97 |
98 |
99 | def handle():
100 | while True:
101 | msg = read_netstring(s).decode("utf-8")
102 | try:
103 | req = json.loads(msg)
104 | completions = complete(embedded_shell, req)
105 | result = (req["text"], completions)
106 | res = json.dumps(result)
107 | send_netstring(s, res)
108 | except Exception:
109 | send_netstring(s, "[]")
110 |
111 | if ac_port:
112 | t = threading.Thread(target=handle)
113 | t.start()
114 |
115 | embedded_shell.start()
116 |
117 | if ac_port:
118 | s.close()
119 |
--------------------------------------------------------------------------------
/repls/repl.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2011, Wojciech Bederski (wuub.net)
3 | # All rights reserved.
4 | # See LICENSE.txt for details.
5 |
6 | from uuid import uuid4
7 | from codecs import getincrementaldecoder, getencoder
8 |
9 |
10 | class NoReplError(LookupError):
11 | """Looking for Repl subclass failed"""
12 | pass
13 |
14 | class Repl(object):
15 | """Class that represents a process that is being executed.
16 | For example this can be python, bash or a telnet session"""
17 |
18 | TYPE = ""
19 |
20 | @classmethod
21 | def subclass(cls, type):
22 | """Returns subclass of Repl of given type eq. SubprocessRepl"""
23 | todo = [cls]
24 | seen = set()
25 | while True:
26 | if not todo:
27 | raise NoReplError
28 | cur = todo.pop()
29 | if cur in seen:
30 | continue
31 | if cur.TYPE == type:
32 | return cur
33 | todo.extend(cur.__subclasses__())
34 |
35 | def __init__(self, encoding, external_id=None, cmd_postfix="\n", suppress_echo=False,
36 | additional_scopes=None, apiv2=False):
37 | self.id = uuid4().hex
38 | self._encoding = encoding
39 | self.decoder = getincrementaldecoder(self._encoding)()
40 | self.encoder = getencoder(encoding)
41 | self.external_id = external_id
42 | self.cmd_postfix = cmd_postfix
43 | self.suppress_echo = suppress_echo
44 | self.additional_scopes = additional_scopes or []
45 | self.apiv2 = apiv2
46 |
47 | def autocomplete_available(self):
48 | return False
49 |
50 | def autocomplete_completions(self, whole_line, pos_in_line, prefix, whole_prefix, locations):
51 | raise NotImplementedError
52 |
53 | def allow_restarts(self):
54 | """Override if for some reason restart logic should not be
55 | used for this REPL"""
56 | return True
57 |
58 | def close(self):
59 | if self.is_alive():
60 | self.kill()
61 |
62 | def name(self):
63 | """Returns name of this repl that should be used as a filename"""
64 | return NotImplementedError
65 |
66 | def is_alive(self):
67 | """ Returns true if the undelying process is stil working"""
68 | raise NotImplementedError
69 |
70 | def write_bytes(self, bytes):
71 | raise NotImplementedError
72 |
73 | def read_bytes(self):
74 | """Reads at lest one byte of Repl output. Returns None if output died.
75 | Can block!!!"""
76 | raise NotImplementedError
77 |
78 | def kill(self):
79 | """Kills the underlying repl"""
80 | raise NotImplementedError
81 |
82 | def write(self, command):
83 | """Encodes and evaluates a given command"""
84 | (bytes, how_many) = self.encoder(command)
85 | return self.write_bytes(bytes)
86 |
87 | def reset_decoder(self):
88 | self.decoder = getincrementaldecoder(self._encoding)()
89 |
90 | def read(self):
91 | """Reads at least one decoded char of output"""
92 | while True:
93 | bs = self.read_bytes()
94 | if not bs:
95 | return None
96 | try:
97 | output = self.decoder.decode(bs)
98 | except Exception as e:
99 | output = "■"
100 | self.reset_decoder()
101 | if output:
102 | return output
103 |
--------------------------------------------------------------------------------
/repls/sublimehaskell_repl.py:
--------------------------------------------------------------------------------
1 | import re
2 | import os
3 | import sublime
4 |
5 | from .subprocess_repl import SubprocessRepl
6 |
7 | def get_settings():
8 | return sublime.load_settings("SublimeHaskell.sublime-settings")
9 |
10 | def get_setting(key, default=None):
11 | "This should be used only from main thread"
12 | # Get setting
13 | return get_settings().get(key, default)
14 |
15 | def ghci_package_db():
16 | dev = get_setting('use_cabal_dev')
17 | box = get_setting('cabal_dev_sandbox')
18 | if dev and box:
19 | package_conf = (filter(lambda x: re.match('packages-(.*)\.conf', x), os.listdir(box)) + [None])[0]
20 | if package_conf:
21 | return os.path.join(box, package_conf)
22 | return None
23 |
24 | def ghci_append_package_db(cmd):
25 | package_conf = ghci_package_db()
26 | if package_conf:
27 | cmd.extend(['-package-db', package_conf])
28 | return cmd
29 |
30 | def ghci_get_min_whitespace_prefix(lines):
31 | line_spaces = [len(line) - len(line.lstrip()) for line in lines]
32 | if not line_spaces:
33 | return 0
34 | min_spaces = min(line_spaces)
35 | return min_spaces
36 |
37 | def ghci_inject_let(lines):
38 | fixed_lines = [line for line in lines if not line.isspace()]
39 |
40 | letprefix = "let "
41 | spaceprefix = " "
42 |
43 | # matches eg. "func x y z ="
44 | # must start lowercase at start of line
45 | # remaining chars must be upper or lowercase letters, numbers, _ or '
46 | if fixed_lines and (not fixed_lines[0].startswith("let ")) and re.search("\A([a-z](\w|['_])*[ ]).*[=][ ]", lines[0]):
47 | fixed_lines[0] = letprefix + fixed_lines[0]
48 | fixed_lines[1:] = [spaceprefix + line for line in fixed_lines[1:]]
49 |
50 | return fixed_lines
51 |
52 | def ghci_remove_whitespace(lines):
53 | # remove lines that are completely whitespace
54 | lines = [line for line in lines if not line.isspace()]
55 |
56 | # remove extra whitespace for more flexible block execution
57 | min_spaces = ghci_get_min_whitespace_prefix(lines)
58 |
59 | # remove the minimum number of spaces over all lines from each
60 | fixed_lines = [line[min_spaces:] for line in lines]
61 | return fixed_lines
62 |
63 | def ghci_wrap_multiline_syntax(lines):
64 | # wrap in mutli-line syntax if more than one line
65 | if len(lines) <= 1:
66 | return lines
67 | fixed_lines = [":{" + os.linesep] + lines + [os.linesep + ":}" + os.linesep]
68 | return fixed_lines
69 |
70 | class SublimeHaskellRepl(SubprocessRepl):
71 | TYPE = "sublime_haskell"
72 |
73 | def __init__(self, encoding, cmd=None, **kwds):
74 | super(SublimeHaskellRepl, self).__init__(encoding, cmd=ghci_append_package_db(cmd), **kwds)
75 |
76 | def write(self, command):
77 | setting_multiline = get_setting('format_multiline', True)
78 | setting_trimwhitespace = get_setting('format_trim_whitespace', True)
79 | setting_injectlet = get_setting('format_inject_let', True)
80 |
81 | new_cmd = ""
82 | if command.isspace() or (not setting_multiline and not setting_trimwhitespace):
83 | new_cmd = command
84 | else:
85 | lines = command.splitlines(True)
86 | if setting_trimwhitespace:
87 | lines = ghci_remove_whitespace(lines)
88 | if setting_injectlet:
89 | lines = ghci_inject_let(lines)
90 | if setting_multiline:
91 | lines = ghci_wrap_multiline_syntax(lines)
92 | new_cmd = "".join(lines)
93 | return super(SublimeHaskellRepl, self).write(new_cmd)
94 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SublimeREPL for SublimeText (2 and 3)
2 | =====================================
3 |
4 |
5 | [](http://waffle.io/wuub/SublimeREPL)
6 |
7 | If you would like to donate to support SublimeREPL development, you can do so using [GitTip](https://www.gittip.com/wuub/) or [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4DGEPH7QAVHH6&lc=GB&item_name=SublimeREPL¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted). Someone willing to take care of documentation would also be very welcome :-)
8 |
9 |
10 | Features
11 | --------
12 |
13 | #### Common
14 | * Run an interpreter (REPL) inside SublimeText2 view/tab.
15 | * Per-language persistent REPL history.
16 | * Easily evaluate code in the running REPL
17 | * Replace your current build system, and use stdin in your programs.
18 | * Rich configuration with platform specific settings, project/file dependent environment variables and sane defaults.
19 |
20 | #### Python
21 | * Launch python in local or remote(1) virtualenv.
22 | * Quickly run selected script or launch PDB.
23 | * Use SublimeText2 Python console with history and multiline input.
24 |
25 | (1) - (ssh, linux/osx only)
26 |
27 | Screenshots
28 | -----------
29 | #### Running python code in SublimeREPL
30 | 
31 | #### R on Windows
32 | 
33 |
34 | Videos
35 | ------
36 | *  [Python & virtualenv over SSH](http://youtu.be/zodAqBvKQm0)
37 | *  [SBT integration demo](http://youtu.be/1Y7Mr_RJpmU)
38 |
39 |
40 | Installation
41 | ============
42 |
43 | 1. Install Package Control. [http://wbond.net/sublime_packages/package_control](http://wbond.net/sublime_packages/package_control)
44 | 2. Install SublimeREPL
45 | 1. `Preferences | Package Control | Package Control: Install Package`
46 | 2. Choose `SublimeREPL`
47 | 3. Restart SublimeText2
48 | 4. Configure `SublimeREPL` (default settings in `Preferences | Package Settings | SublimeREPL | Settings - Default` should be modified in `Preferences | Package Settings | SublimeREPL | Settings - User`, this way they will survive package upgrades!
49 |
50 | Documentation
51 | =============
52 |
53 | Very basic documentation will soon be available on RTD: [http://sublimerepl.readthedocs.org/](http://sublimerepl.readthedocs.org/)
54 |
55 | #### Getting started
56 |
57 | * Create or open your file with code.
58 | * Menu / Tools / Command Palette (OS X: `⇧⌘P`)
59 | then type "SublimeREPL" and select the approperiate language.
60 | * Menu / View / Layout / Rows: 2 (OS X: `⌥⇧⌘2`).
61 | * Menu / View / Move File to Group / Group 2 (`⌃⇧2`).
62 |
63 | #### Keybindings
64 |
65 | * Evaluate in REPL:
66 | * ctrl+,, s Selection
67 | * ctrl+,, f File
68 | * ctrl+,, l Lines
69 | * ctrl+,, b Block
70 | * Transfer in REPL (just copy, without evaluating it):
71 | * ctrl+shift+,, s Selection
72 | * ctrl+shift+,, f File
73 | * ctrl+shift+,, l Lines
74 | * ctrl+shift+,, b Block
75 |
76 | Note: ctrl+,, f means: press Ctrl and Comma, release all, press F.
77 |
78 |
79 | License and Price
80 | =================
81 |
82 | Since version 1.2.0 SublimeREPL is licensed under GPL. Previous versions were licensed under BSD.
83 | If you're using SublimeREPL in commercial environment a donation is strongly encouraged ;-)
84 |
85 | Compatibility
86 | ================
87 |
88 | SublimeREPL is developed against the latest dev build of SublimeText3.
89 | Ubuntu 13.04 is main
90 |
--------------------------------------------------------------------------------
/config/Python/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Python",
12 | "id": "Python",
13 |
14 | "children":[
15 | {"command": "repl_open",
16 | "caption": "Python",
17 | "id": "repl_python",
18 | "mnemonic": "P",
19 | "args": {
20 | "type": "subprocess",
21 | "encoding": "utf8",
22 | "cmd": ["python", "-i", "-u"],
23 | "cwd": "$file_path",
24 | "syntax": "Packages/Python/Python.tmLanguage",
25 | "external_id": "python",
26 | "extend_env": {"PYTHONIOENCODING": "utf-8"}
27 | }
28 | },
29 | {"command": "python_virtualenv_repl",
30 | "id": "python_virtualenv_repl",
31 | "caption": "Python - virtualenv"},
32 | {"command": "repl_open",
33 | "caption": "Python - PDB current file",
34 | "id": "repl_python_pdb",
35 | "mnemonic": "D",
36 | "args": {
37 | "type": "subprocess",
38 | "encoding": "utf8",
39 | "cmd": ["python", "-i", "-u", "-m", "pdb", "$file_basename"],
40 | "cwd": "$file_path",
41 | "syntax": "Packages/Python/Python.tmLanguage",
42 | "external_id": "python",
43 | "extend_env": {"PYTHONIOENCODING": "utf-8"}
44 | }
45 | },
46 | {"command": "repl_open",
47 | "caption": "Python - RUN current file",
48 | "id": "repl_python_run",
49 | "mnemonic": "R",
50 | "args": {
51 | "type": "subprocess",
52 | "encoding": "utf8",
53 | "cmd": ["python", "-u", "$file_basename"],
54 | "cwd": "$file_path",
55 | "syntax": "Packages/Python/Python.tmLanguage",
56 | "external_id": "python",
57 | "extend_env": {"PYTHONIOENCODING": "utf-8"}
58 | }
59 | },
60 | {"command": "repl_open",
61 | "caption": "Python - IPython",
62 | "id": "repl_python_ipython",
63 | "mnemonic": "I",
64 | "args": {
65 | "type": "subprocess",
66 | "encoding": "utf8",
67 | "autocomplete_server": true,
68 | "cmd": {
69 | "osx": ["python", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"],
70 | "linux": ["python", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"],
71 | "windows": ["python", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"]
72 | },
73 | "cwd": "$file_path",
74 | "syntax": "Packages/Python/Python.tmLanguage",
75 | "external_id": "python",
76 | "extend_env": {
77 | "PYTHONIOENCODING": "utf-8",
78 | "SUBLIMEREPL_EDITOR": "$editor"
79 | }
80 | }
81 | }
82 | ]}
83 | ]
84 | }]
85 | }
86 | ]
87 |
--------------------------------------------------------------------------------
/SublimeREPL.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | // default_extend_env are used to augment any environment variables
3 | // that should be visible for all subprocess repls launched within
4 | // SublimeREPL. This is a very good place to add PATH extension
5 | // once "PATH": "{PATH}:/home/username/mylocalinstalls/bin" or whatever
6 | "default_extend_env": {},
7 |
8 | // Specify whether to move repls to a different Sublime Text group (frame)
9 | // immediately on opening. Setting this to true will simply move it to
10 | // the 'next' group from the one that was in focus when it was opened
11 | // (one down with row layout, one to the right with column and grid
12 | // layout). Alternatively, you can set this to the index of the group in
13 | // which you want all repls to be opened (index 0 being the top-left group).
14 | // Activating this option will NOT automatically change your layout/create
15 | // a new group if it isn't open.
16 | "open_repl_in_group": true,
17 |
18 | // Persistent history is stored per REPL external_id, it means that all python
19 | // REPLS will share history. If you wish you can disable history altogether
20 | "persistent_history_enabled": true,
21 |
22 | // By default SublimeREPL leaves REPL view open once the underlying subprocess
23 | // dies or closes connection. This is useful when the process dies for an unexpected
24 | // reason as it allows you to inspect it output. If you want. Setting this
25 | // to true will cause SublimreREPL to close view once the process died.
26 | "view_auto_close": false,
27 |
28 | // On POSIX system SublimeText launched from GUI does not inherit
29 | // a proper environment. Often leading to problems with finding interpreters
30 | // or not using the ones affected by changes in ~/.profile / *rc files
31 | // This command is used as a workaround, it's launched before any subprocess
32 | // repl starts and it's output is parsed as an environment
33 | "getenv_command": ["/bin/bash", "--login", "-c", "env"],
34 |
35 | // Some terminals output ascii color codes which are not currently supported
36 | // enable this option to filter them out.
37 | "filter_ascii_color_codes": true,
38 |
39 | // Where to look for python virtualenvs
40 | "python_virtualenv_paths": [
41 | "~/.virtualenvs", // virtualenvwrapper
42 | "~/.venv" // venv.bash https://github.com/wuub/venv
43 | ],
44 |
45 | // Use arrows for history navigation instead of Alt+[P|N]/Ctrl+[P|N]
46 | "history_arrows": true,
47 |
48 | // standard sublime view settings that will be overwritten on each repl view
49 | // this has to be customized as a whole dictionary
50 | "repl_view_settings": {
51 | "translate_tabs_to_spaces": false,
52 | "auto_indent": false,
53 | "smart_indent": false,
54 | "spell_check": false,
55 | "indent_subsequent_lines": false,
56 | "detect_indentation": false,
57 | "auto_complete": true,
58 | "line_numbers": false,
59 | "gutter": false
60 | },
61 |
62 | // this settings exposes additional variables in repl config files, especially
63 | // those related to sublime projects that are not available through standard API
64 | // WARNING: this will switch your build system back to Automatic each time a REPL
65 | // is started so beware!
66 | "use_build_system_hack": false,
67 |
68 | // IP address used to setup autocomplete server in sublimerepl.
69 | // changing this is usefull when you want to exclude one address
70 | // from proxychains/tsocks routing
71 | "autocomplete_server_ip": "127.0.0.1",
72 |
73 | // Mapping is used, when external_id of REPL does not match
74 | // source.[xxx] scope of syntax definition used to highlight
75 | // files from which text is being transfered. For example octave
76 | // repls use source.matlab syntax files and w/o this mapping text transfer
77 | // will not work
78 | "external_id_mapping": {
79 | "octave": "matlab"
80 | },
81 |
82 | // If set to true, SublimeREPL will try to append evaluated code to repl
83 | // output before evaluation (e.g. Ctrl+, f)
84 | "show_transferred_text": false,
85 |
86 | // If set to true repl view (tab) that receives text for evaluation will
87 | // be brought to front after text transfer. Note: This will not fire if repl view
88 | // is in the same tab group as the view from which the code is sent.
89 | "focus_view_on_transfer": true
90 | }
91 |
--------------------------------------------------------------------------------
/Default (Windows).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["up"], "command": "repl_view_previous",
3 | "context":
4 | [
5 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
6 | { "key": "setting.repl", "operator": "equal", "operand": true },
7 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
8 | ]
9 | },
10 | { "keys": ["alt+p"], "command": "repl_view_previous",
11 | "context":
12 | [
13 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
14 | { "key": "setting.repl", "operator": "equal", "operand": true }
15 | ]
16 | },
17 | { "keys": ["down"], "command": "repl_view_next",
18 | "context":
19 | [
20 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
21 | { "key": "setting.repl", "operator": "equal", "operand": true },
22 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
23 | ]
24 | },
25 | { "keys": ["alt+n"], "command": "repl_view_next",
26 | "context":
27 | [
28 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
29 | { "key": "setting.repl", "operator": "equal", "operand": true }
30 | ]
31 | },
32 | { "keys": ["enter"], "command": "repl_enter", "args": {},
33 | "context":
34 | [
35 | { "key": "setting.repl", "operator": "equal", "operand": true },
36 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
37 | ]
38 | },
39 | { "keys": ["enter"], "command": "repl_enter", "args": {},
40 | "context":
41 | [
42 | { "key": "setting.repl", "operator": "equal", "operand": true },
43 | { "key": "setting.auto_complete_commit_on_tab", "operand": true }
44 | ]
45 | },
46 | { "keys": ["escape"], "command": "repl_escape", "args": {},
47 | "context":
48 | [
49 | { "key": "auto_complete_visible", "operator": "equal", "operand": false },
50 | { "key": "setting.repl", "operator": "equal", "operand": true }
51 | ]
52 | },
53 | { "keys": ["backspace"], "command": "repl_backspace", "args": {},
54 | "context":
55 | [
56 | { "key": "setting.repl", "operator": "equal", "operand": true },
57 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
58 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
59 | ]
60 | },
61 | { "keys": ["ctrl+backspace"], "command": "repl_ctrl_backspace", "args": {},
62 | "context":
63 | [
64 | { "key": "setting.repl", "operator": "equal", "operand": true },
65 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
66 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
67 | ]
68 | },
69 | { "keys": ["left"], "command": "repl_left", "args": {},
70 | "context":
71 | [
72 | { "key": "setting.repl", "operator": "equal", "operand": true }
73 | ]
74 | },
75 | { "keys": ["home"], "command": "repl_home", "args": {},
76 | "context":
77 | [
78 | { "key": "setting.repl", "operator": "equal", "operand": true }
79 | ]
80 | },
81 | { "keys": ["shift+left"], "command": "repl_shift_left", "args": {},
82 | "context":
83 | [
84 | { "key": "setting.repl", "operator": "equal", "operand": true }
85 | ]
86 | },
87 | { "keys": ["shift+home"], "command": "repl_shift_home", "args": {},
88 | "context":
89 | [
90 | { "key": "setting.repl", "operator": "equal", "operand": true }
91 | ]
92 | },
93 | { "keys": ["shift+ctrl+c"], "command": "repl_clear",
94 | "context":
95 | [
96 | { "key": "setting.repl", "operator": "equal", "operand": true }
97 | ]
98 | },
99 |
100 |
101 | { "keys": ["ctrl+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection"}},
102 | { "keys": ["ctrl+shift+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection", "action":"view_write"}},
103 | { "keys": ["ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file"}},
104 | { "keys": ["shift+ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file", "action":"view_write"}},
105 | { "keys": ["ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines"}},
106 | { "keys": ["shift+ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines", "action":"view_write"}},
107 | { "keys": ["ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block"}},
108 | { "keys": ["shift+ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block", "action":"view_write"}}
109 | ]
110 |
--------------------------------------------------------------------------------
/Default (Linux).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["up"], "command": "repl_view_previous",
3 | "context":
4 | [
5 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
6 | { "key": "setting.repl", "operator": "equal", "operand": true },
7 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
8 | ]
9 | },
10 | { "keys": ["alt+p"], "command": "repl_view_previous",
11 | "context":
12 | [
13 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
14 | { "key": "setting.repl", "operator": "equal", "operand": true }
15 | ]
16 | },
17 | { "keys": ["down"], "command": "repl_view_next",
18 | "context":
19 | [
20 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
21 | { "key": "setting.repl", "operator": "equal", "operand": true },
22 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
23 | ]
24 | },
25 | { "keys": ["alt+n"], "command": "repl_view_next",
26 | "context":
27 | [
28 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
29 | { "key": "setting.repl", "operator": "equal", "operand": true }
30 | ]
31 | },
32 | { "keys": ["enter"], "command": "repl_enter", "args": {},
33 | "context":
34 | [
35 | { "key": "setting.repl", "operator": "equal", "operand": true },
36 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
37 | ]
38 | },
39 | { "keys": ["enter"], "command": "repl_enter", "args": {},
40 | "context":
41 | [
42 | { "key": "setting.repl", "operator": "equal", "operand": true },
43 | { "key": "setting.auto_complete_commit_on_tab", "operand": true }
44 | ]
45 | },
46 | { "keys": ["escape"], "command": "repl_escape", "args": {},
47 | "context":
48 | [
49 | { "key": "auto_complete_visible", "operator": "equal", "operand": false },
50 | { "key": "setting.repl", "operator": "equal", "operand": true }
51 | ]
52 | },
53 | { "keys": ["backspace"], "command": "repl_backspace", "args": {},
54 | "context":
55 | [
56 | { "key": "setting.repl", "operator": "equal", "operand": true },
57 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
58 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
59 | ]
60 | },
61 | { "keys": ["ctrl+backspace"], "command": "repl_ctrl_backspace", "args": {},
62 | "context":
63 | [
64 | { "key": "setting.repl", "operator": "equal", "operand": true },
65 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
66 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
67 | ]
68 | },
69 | { "keys": ["left"], "command": "repl_left", "args": {},
70 | "context":
71 | [
72 | { "key": "setting.repl", "operator": "equal", "operand": true }
73 | ]
74 | },
75 | { "keys": ["home"], "command": "repl_home", "args": {},
76 | "context":
77 | [
78 | { "key": "setting.repl", "operator": "equal", "operand": true }
79 | ]
80 | },
81 | { "keys": ["shift+left"], "command": "repl_shift_left", "args": {},
82 | "context":
83 | [
84 | { "key": "setting.repl", "operator": "equal", "operand": true }
85 | ]
86 | },
87 | { "keys": ["shift+home"], "command": "repl_shift_home", "args": {},
88 | "context":
89 | [
90 | { "key": "setting.repl", "operator": "equal", "operand": true }
91 | ]
92 | },
93 | { "keys": ["ctrl+l"], "command": "repl_clear",
94 | "context":
95 | [
96 | { "key": "setting.repl", "operator": "equal", "operand": true }
97 | ]
98 | },
99 | { "keys": ["shift+ctrl+c"], "command": "subprocess_repl_send_signal", "args": {"signal": 2}, // sigint
100 | "context":
101 | [
102 | { "key": "setting.repl", "operator": "equal", "operand": true }
103 | ]
104 | },
105 |
106 |
107 | { "keys": ["ctrl+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection"}},
108 | { "keys": ["ctrl+shift+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection", "action":"view_write"}},
109 | { "keys": ["ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file"}},
110 | { "keys": ["shift+ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file", "action":"view_write"}},
111 | { "keys": ["ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines"}},
112 | { "keys": ["shift+ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines", "action":"view_write"}},
113 | { "keys": ["ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block"}},
114 | { "keys": ["shift+ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block", "action":"view_write"}}
115 | ]
116 |
117 |
--------------------------------------------------------------------------------
/config/Io/repl.io:
--------------------------------------------------------------------------------
1 | # This code is modified Z_CLI.io from https://github.com/stevedekorte/io/blob/master/libs/iovm/io/Z_CLI.io
2 | Locals removeSlot("doFile")
3 |
4 | DummyLine := File standardInput do(
5 | readLine := method(prompt,
6 | if(prompt, prompt print; File flush)
7 | resend
8 | )
9 | )
10 |
11 | CLI := Object clone do(
12 | prompt ::= "Io> "
13 | outPrompt ::= "==> "
14 | continuedLinePrompt ::= "... "
15 |
16 | isRunning ::= true # Get rid of this ...
17 | commandLineLabel ::= "Command Line" # and this?
18 |
19 | context ::= lazySlot(
20 | Lobby do(
21 | # Python-style underscore, stores the result of the previous computation.
22 | # Example:
23 | # Io> 1 + 1
24 | # ==> 2
25 | # Io> _ == 2
26 | # ==> true
27 | _ ::= nil
28 |
29 | exit := method(CLI stop)
30 | )
31 | )
32 |
33 | lineReader := lazySlot(
34 | # This might look as a `hack`, but why not use stdin as the default
35 | # reader, since it shares the same interface with Read(Edit)Line,
36 | # i.e. readLine.
37 | reader := DummyLine
38 |
39 | # Trying to use GNU ReadLine as the default line reader, falling
40 | # back to EditLine, if the attempt failed.
41 | try(reader := ReadLine) catch(Exception,
42 | try(reader := EditLine)
43 | )
44 | reader
45 | )
46 |
47 | # A list of error messages for the errors we understand.
48 | knownErrors := lazySlot(
49 | list("(", "[", "{", "\"\"\"", "(x,") map(error,
50 | self errorMessage(try(error asMessage) error)
51 | )
52 | )
53 |
54 | errorMessage := method(error, error beforeSeq(" on line"))
55 |
56 | doFile := method(path,
57 | System launchPath = if(Path isPathAbsolute(path),
58 | path
59 | ,
60 | System launchPath asMutable appendPathSeq(path)
61 | ) pathComponent
62 |
63 | System launchScript = path
64 |
65 | context doFile(path)
66 | )
67 |
68 | doLine := method(lineAsMessage,
69 | # Execute the line and report any exceptions which happened.
70 | executionError := try(result := context doMessage(lineAsMessage))
71 | if(executionError,
72 | executionError showStack
73 | ,
74 | # Write out the command's result to stdout; nothing is written
75 | # if the CLI is terminated, this condition is satisfied, only
76 | # when CLI exit() was called.
77 | if(isRunning,
78 | context set_(getSlot("result"))
79 | writeCommandResult(getSlot("result")))
80 | )
81 | )
82 |
83 | doIorc := method(
84 | # Note: Probably won't work on Windows, since it uses %HOMEPATH%
85 | # and %HOMEDRIVE% pair to indentify user's home directory.
86 | home := System getEnvironmentVariable("HOME")
87 | if(home,
88 | path := Path with(home, ".iorc")
89 | if(File with(path) exists,
90 | context doFile(path)
91 | )
92 | )
93 | )
94 |
95 | writeWelcomeBanner := method("Io #{System version}" interpolate println)
96 | writeCommandResult := method(result,
97 | outPrompt print
98 |
99 | if(exc := try(getSlot("result") asString println),
100 | "" println
101 | exc showStack
102 | )
103 | )
104 |
105 | stop := method(setIsRunning(false))
106 |
107 | interactive := method(
108 | # Start with the default prompt. The prompt is changed for continued lines,
109 | # and errors.
110 | prompt := self prompt
111 | line := ""
112 | # If there are unmatched (, {, [ or the command ends with a \ then we'll
113 | # need to read multiple lines.
114 | loop(
115 | # Write out prompt and read line.
116 | if(nextLine := lineReader readLine(prompt),
117 | # Add what we read to the line we've been building up
118 | line = line .. nextLine
119 | ,
120 | # Note: readLine method returns nil if ^D was pressed.
121 | context exit
122 | "\n" print # Fixing the newline issue.
123 | )
124 |
125 | compileError := try(
126 | lineAsMessage := line asMessage setLabel(commandLineLabel)
127 | )
128 |
129 | if(compileError,
130 | # Not sure that, displaying a different notification for
131 | # each error actually makes sense.
132 | if(nextLine size > 0 and errorMessage(compileError error) in(knownErrors),
133 | prompt = continuedLinePrompt
134 | continue
135 | )
136 | # If the error can't be fixed by continuing the line - report it.
137 | compileError showStack
138 | ,
139 | doLine(lineAsMessage)
140 | )
141 |
142 | return if(isRunning, interactive, nil)
143 | )
144 | )
145 | )
146 |
147 | CLI interactive
148 |
--------------------------------------------------------------------------------
/config/CommonLisp/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "children":
5 | [{
6 | "caption": "SublimeREPL",
7 | "mnemonic": "R",
8 | "id": "SublimeREPL",
9 | "children":
10 | [
11 | {"caption": "Common Lisp",
12 | "id": "CommonLisp",
13 |
14 | "children":[
15 | {"command": "repl_open",
16 | "caption": "Clozure CL",
17 | "id": "repl_ccl",
18 | "mnemonic": "C",
19 | "args": {
20 | "type": "subprocess",
21 | "encoding": "utf8",
22 | "external_id": "lisp",
23 | "cmd": ["ccl"],
24 | "soft_quit": "\n(ccl:quit)\n",
25 | "cwd": "$folder",
26 | "cmd_postfix": "\n",
27 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
28 | }
29 | },
30 | {"command": "repl_open",
31 | "caption": "SBCL",
32 | "id": "repl_sbcl",
33 | "mnemonic": "S",
34 | "args": {
35 | "type": "subprocess",
36 | "encoding": "utf8",
37 | "external_id": "lisp",
38 | "cmd": ["sbcl"],
39 | "soft_quit": "\n(sb-ext:exit)\n",
40 | "cwd": "$folder",
41 | "cmd_postfix": "\n",
42 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
43 | }
44 | },
45 | {"command": "repl_open",
46 | "caption": "GNU Clisp",
47 | "id": "repl_clisp",
48 | "mnemonic": "G",
49 | "args": {
50 | "type": "subprocess",
51 | "encoding": "utf8",
52 | "external_id": "lisp",
53 | "cmd": ["clisp", "-disable-readline"],
54 | "soft_quit": "\n(ext:quit)\n",
55 | "cwd": "$folder",
56 | "cmd_postfix": "\n",
57 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
58 | }
59 | },
60 | {"command": "repl_open",
61 | "caption": "Allegro CL",
62 | "id": "repl_allegro",
63 | "mnemonic": "A",
64 | "args": {
65 | "type": "subprocess",
66 | "encoding": "utf8",
67 | "external_id": "lisp",
68 | "cmd": ["alisp"],
69 | "soft_quit": "\n(excl:exit 0 :quiet t)\n",
70 | "cwd": "$folder",
71 | "cmd_postfix": "\n",
72 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
73 | }
74 | },
75 | {"command": "repl_open",
76 | "caption": "ABCL",
77 | "id": "repl_abcl",
78 | "mnemonic": "B",
79 | "args": {
80 | "type": "subprocess",
81 | "encoding": "utf8",
82 | "external_id": "lisp",
83 | "cmd": ["abcl"],
84 | "soft_quit": "\n(ext:exit)\n",
85 | "cwd": "$folder",
86 | "cmd_postfix": "\n",
87 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
88 | }
89 | },
90 | {"command": "repl_open",
91 | "caption": "CMUCL",
92 | "id": "repl_cmucl",
93 | "mnemonic": "M",
94 | "args": {
95 | "type": "subprocess",
96 | "encoding": "utf8",
97 | "external_id": "lisp",
98 | "cmd": ["lisp"],
99 | "soft_quit": "\n(ext::quit)\n",
100 | "cwd": "$folder",
101 | "cmd_postfix": "\n",
102 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
103 | }
104 | },
105 | {"command": "repl_open",
106 | "caption": "ECL",
107 | "id": "repl_ecl",
108 | "mnemonic": "E",
109 | "args": {
110 | "type": "subprocess",
111 | "encoding": "utf8",
112 | "external_id": "lisp",
113 | "cmd": ["ecl"],
114 | "soft_quit": "\n(ext:quit)\n",
115 | "cwd": "$folder",
116 | "cmd_postfix": "\n",
117 | "syntax": "Packages/Lisp/Lisp.tmLanguage"
118 | }
119 | }
120 | ]}
121 | ]
122 | }]
123 | }
124 | ]
125 |
--------------------------------------------------------------------------------
/Default (OSX).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["up"], "command": "repl_view_previous",
3 | "context":
4 | [
5 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
6 | { "key": "setting.repl", "operator": "equal", "operand": true },
7 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
8 | ]
9 | },
10 | { "keys": ["ctrl+p"], "command": "repl_view_previous",
11 | "context":
12 | [
13 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
14 | { "key": "setting.repl", "operator": "equal", "operand": true }
15 | ]
16 | },
17 | { "keys": ["down"], "command": "repl_view_next",
18 | "context":
19 | [
20 | { "key": "setting.history_arrows", "operator": "equal", "operand": true },
21 | { "key": "setting.repl", "operator": "equal", "operand": true },
22 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
23 | ]
24 | },
25 | { "keys": ["ctrl+n"], "command": "repl_view_next",
26 | "context":
27 | [
28 | { "key": "setting.history_arrows", "operator": "equal", "operand": false },
29 | { "key": "setting.repl", "operator": "equal", "operand": true }
30 | ]
31 | },
32 | { "keys": ["enter"], "command": "repl_enter", "args": {},
33 | "context":
34 | [
35 | { "key": "setting.repl", "operator": "equal", "operand": true },
36 | { "key": "auto_complete_visible", "operator": "equal", "operand": false }
37 | ]
38 | },
39 | { "keys": ["enter"], "command": "repl_enter", "args": {},
40 | "context":
41 | [
42 | { "key": "setting.repl", "operator": "equal", "operand": true },
43 | { "key": "setting.auto_complete_commit_on_tab", "operand": true }
44 | ]
45 | },
46 | { "keys": ["escape"], "command": "repl_escape", "args": {},
47 | "context":
48 | [
49 | { "key": "auto_complete_visible", "operator": "equal", "operand": false },
50 | { "key": "setting.repl", "operator": "equal", "operand": true }
51 | ]
52 | },
53 | { "keys": ["backspace"], "command": "repl_backspace", "args": {},
54 | "context":
55 | [
56 | { "key": "setting.repl", "operator": "equal", "operand": true },
57 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
58 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
59 | ]
60 | },
61 | { "keys": ["ctrl+backspace"], "command": "repl_ctrl_backspace", "args": {},
62 | "context":
63 | [
64 | { "key": "setting.repl", "operator": "equal", "operand": true },
65 | { "key": "setting.repl_sublime2", "operator": "equal", "operand": true },
66 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
67 | ]
68 | },
69 | { "keys": ["super+backspace"], "command": "repl_super_backspace", "args": {},
70 | "context":
71 | [
72 | { "key": "setting.repl", "operator": "equal", "operand": true },
73 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
74 | ]
75 | },
76 | { "keys": ["alt+backspace"], "command": "repl_ctrl_backspace", "args": {},
77 | "context":
78 | [
79 | { "key": "setting.repl", "operator": "equal", "operand": true },
80 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
81 | ]
82 | },
83 | { "keys": ["left"], "command": "repl_left", "args": {},
84 | "context":
85 | [
86 | { "key": "setting.repl", "operator": "equal", "operand": true }
87 | ]
88 | },
89 | { "keys": ["home"], "command": "repl_home", "args": {},
90 | "context":
91 | [
92 | { "key": "setting.repl", "operator": "equal", "operand": true }
93 | ]
94 | },
95 | { "keys": ["ctrl+a"], "command": "repl_home", "args": {},
96 | "context":
97 | [
98 | { "key": "setting.repl", "operator": "equal", "operand": true }
99 | ]
100 | },
101 | { "keys": ["shift+left"], "command": "repl_shift_left", "args": {},
102 | "context":
103 | [
104 | { "key": "setting.repl", "operator": "equal", "operand": true }
105 | ]
106 | },
107 | { "keys": ["shift+home"], "command": "repl_shift_home", "args": {},
108 | "context":
109 | [
110 | { "key": "setting.repl", "operator": "equal", "operand": true }
111 | ]
112 | },
113 | { "keys": ["ctrl+l"], "command": "repl_clear",
114 | "context":
115 | [
116 | { "key": "setting.repl", "operator": "equal", "operand": true }
117 | ]
118 | },
119 | { "keys": ["shift+ctrl+c"], "command": "subprocess_repl_send_signal", "args": {"signal": 2}, // sigint
120 | "context":
121 | [
122 | { "key": "setting.repl", "operator": "equal", "operand": true }
123 | ]
124 | },
125 |
126 |
127 | { "keys": ["ctrl+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection"}},
128 | { "keys": ["ctrl+shift+,", "s"], "command": "repl_transfer_current", "args": {"scope": "selection", "action":"view_write"}},
129 | { "keys": ["ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file"}},
130 | { "keys": ["shift+ctrl+,", "f"], "command": "repl_transfer_current", "args": {"scope": "file", "action":"view_write"}},
131 | { "keys": ["ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines"}},
132 | { "keys": ["shift+ctrl+,", "l"], "command": "repl_transfer_current", "args": {"scope": "lines", "action":"view_write"}},
133 | { "keys": ["ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block"}},
134 | { "keys": ["shift+ctrl+,", "b"], "command": "repl_transfer_current", "args": {"scope": "block", "action":"view_write"}}
135 | ]
136 |
--------------------------------------------------------------------------------
/doc/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | set I18NSPHINXOPTS=%SPHINXOPTS% .
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. linkcheck to check all external links for integrity
37 | echo. doctest to run all doctests embedded in the documentation if enabled
38 | goto end
39 | )
40 |
41 | if "%1" == "clean" (
42 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
43 | del /q /s %BUILDDIR%\*
44 | goto end
45 | )
46 |
47 | if "%1" == "html" (
48 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
49 | if errorlevel 1 exit /b 1
50 | echo.
51 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
52 | goto end
53 | )
54 |
55 | if "%1" == "dirhtml" (
56 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
57 | if errorlevel 1 exit /b 1
58 | echo.
59 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
60 | goto end
61 | )
62 |
63 | if "%1" == "singlehtml" (
64 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
65 | if errorlevel 1 exit /b 1
66 | echo.
67 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
68 | goto end
69 | )
70 |
71 | if "%1" == "pickle" (
72 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
73 | if errorlevel 1 exit /b 1
74 | echo.
75 | echo.Build finished; now you can process the pickle files.
76 | goto end
77 | )
78 |
79 | if "%1" == "json" (
80 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
81 | if errorlevel 1 exit /b 1
82 | echo.
83 | echo.Build finished; now you can process the JSON files.
84 | goto end
85 | )
86 |
87 | if "%1" == "htmlhelp" (
88 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
89 | if errorlevel 1 exit /b 1
90 | echo.
91 | echo.Build finished; now you can run HTML Help Workshop with the ^
92 | .hhp project file in %BUILDDIR%/htmlhelp.
93 | goto end
94 | )
95 |
96 | if "%1" == "qthelp" (
97 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
98 | if errorlevel 1 exit /b 1
99 | echo.
100 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
101 | .qhcp project file in %BUILDDIR%/qthelp, like this:
102 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SublimeREPL.qhcp
103 | echo.To view the help file:
104 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SublimeREPL.ghc
105 | goto end
106 | )
107 |
108 | if "%1" == "devhelp" (
109 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
110 | if errorlevel 1 exit /b 1
111 | echo.
112 | echo.Build finished.
113 | goto end
114 | )
115 |
116 | if "%1" == "epub" (
117 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
118 | if errorlevel 1 exit /b 1
119 | echo.
120 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
121 | goto end
122 | )
123 |
124 | if "%1" == "latex" (
125 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
129 | goto end
130 | )
131 |
132 | if "%1" == "text" (
133 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
134 | if errorlevel 1 exit /b 1
135 | echo.
136 | echo.Build finished. The text files are in %BUILDDIR%/text.
137 | goto end
138 | )
139 |
140 | if "%1" == "man" (
141 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
142 | if errorlevel 1 exit /b 1
143 | echo.
144 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
145 | goto end
146 | )
147 |
148 | if "%1" == "texinfo" (
149 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
150 | if errorlevel 1 exit /b 1
151 | echo.
152 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
153 | goto end
154 | )
155 |
156 | if "%1" == "gettext" (
157 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
158 | if errorlevel 1 exit /b 1
159 | echo.
160 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
161 | goto end
162 | )
163 |
164 | if "%1" == "changes" (
165 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
166 | if errorlevel 1 exit /b 1
167 | echo.
168 | echo.The overview file is in %BUILDDIR%/changes.
169 | goto end
170 | )
171 |
172 | if "%1" == "linkcheck" (
173 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
174 | if errorlevel 1 exit /b 1
175 | echo.
176 | echo.Link check complete; look for any errors in the above output ^
177 | or in %BUILDDIR%/linkcheck/output.txt.
178 | goto end
179 | )
180 |
181 | if "%1" == "doctest" (
182 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
183 | if errorlevel 1 exit /b 1
184 | echo.
185 | echo.Testing of doctests in the sources finished, look at the ^
186 | results in %BUILDDIR%/doctest/output.txt.
187 | goto end
188 | )
189 |
190 | :end
191 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 | # the i18n builder cannot share the environment and doctrees with the others
15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
16 |
17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
18 |
19 | help:
20 | @echo "Please use \`make ' where is one of"
21 | @echo " html to make standalone HTML files"
22 | @echo " dirhtml to make HTML files named index.html in directories"
23 | @echo " singlehtml to make a single large HTML file"
24 | @echo " pickle to make pickle files"
25 | @echo " json to make JSON files"
26 | @echo " htmlhelp to make HTML files and a HTML help project"
27 | @echo " qthelp to make HTML files and a qthelp project"
28 | @echo " devhelp to make HTML files and a Devhelp project"
29 | @echo " epub to make an epub"
30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
31 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
32 | @echo " text to make text files"
33 | @echo " man to make manual pages"
34 | @echo " texinfo to make Texinfo files"
35 | @echo " info to make Texinfo files and run them through makeinfo"
36 | @echo " gettext to make PO message catalogs"
37 | @echo " changes to make an overview of all changed/added/deprecated items"
38 | @echo " linkcheck to check all external links for integrity"
39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40 |
41 | clean:
42 | -rm -rf $(BUILDDIR)/*
43 |
44 | html:
45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48 |
49 | dirhtml:
50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51 | @echo
52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53 |
54 | singlehtml:
55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56 | @echo
57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58 |
59 | pickle:
60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61 | @echo
62 | @echo "Build finished; now you can process the pickle files."
63 |
64 | json:
65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66 | @echo
67 | @echo "Build finished; now you can process the JSON files."
68 |
69 | htmlhelp:
70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71 | @echo
72 | @echo "Build finished; now you can run HTML Help Workshop with the" \
73 | ".hhp project file in $(BUILDDIR)/htmlhelp."
74 |
75 | qthelp:
76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77 | @echo
78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SublimeREPL.qhcp"
81 | @echo "To view the help file:"
82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SublimeREPL.qhc"
83 |
84 | devhelp:
85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86 | @echo
87 | @echo "Build finished."
88 | @echo "To view the help file:"
89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/SublimeREPL"
90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SublimeREPL"
91 | @echo "# devhelp"
92 |
93 | epub:
94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95 | @echo
96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97 |
98 | latex:
99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100 | @echo
101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
103 | "(use \`make latexpdf' here to do that automatically)."
104 |
105 | latexpdf:
106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107 | @echo "Running LaTeX files through pdflatex..."
108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110 |
111 | text:
112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113 | @echo
114 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
115 |
116 | man:
117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118 | @echo
119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120 |
121 | texinfo:
122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
123 | @echo
124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
125 | @echo "Run \`make' in that directory to run these through makeinfo" \
126 | "(use \`make info' here to do that automatically)."
127 |
128 | info:
129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
130 | @echo "Running Texinfo files through makeinfo..."
131 | make -C $(BUILDDIR)/texinfo info
132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
133 |
134 | gettext:
135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
136 | @echo
137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
138 |
139 | changes:
140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
141 | @echo
142 | @echo "The overview file is in $(BUILDDIR)/changes."
143 |
144 | linkcheck:
145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
146 | @echo
147 | @echo "Link check complete; look for any errors in the above output " \
148 | "or in $(BUILDDIR)/linkcheck/output.txt."
149 |
150 | doctest:
151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
152 | @echo "Testing of doctests in the sources finished, look at the " \
153 | "results in $(BUILDDIR)/doctest/output.txt."
154 |
--------------------------------------------------------------------------------
/repls/killableprocess/qijo.py:
--------------------------------------------------------------------------------
1 | from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE, addressof, c_size_t, c_ulong
2 | from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LARGE_INTEGER
3 |
4 | LPVOID = c_void_p
5 | LPDWORD = POINTER(DWORD)
6 | SIZE_T = c_size_t
7 | ULONG_PTR = POINTER(c_ulong)
8 |
9 | # A ULONGLONG is a 64-bit unsigned integer.
10 | # Thus there are 8 bytes in a ULONGLONG.
11 | # XXX why not import c_ulonglong ?
12 | ULONGLONG = BYTE * 8
13 |
14 | class IO_COUNTERS(Structure):
15 | # The IO_COUNTERS struct is 6 ULONGLONGs.
16 | # TODO: Replace with non-dummy fields.
17 | _fields_ = [('dummy', ULONGLONG * 6)]
18 |
19 | class JOBOBJECT_BASIC_ACCOUNTING_INFORMATION(Structure):
20 | _fields_ = [('TotalUserTime', LARGE_INTEGER),
21 | ('TotalKernelTime', LARGE_INTEGER),
22 | ('ThisPeriodTotalUserTime', LARGE_INTEGER),
23 | ('ThisPeriodTotalKernelTime', LARGE_INTEGER),
24 | ('TotalPageFaultCount', DWORD),
25 | ('TotalProcesses', DWORD),
26 | ('ActiveProcesses', DWORD),
27 | ('TotalTerminatedProcesses', DWORD)]
28 |
29 | class JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION(Structure):
30 | _fields_ = [('BasicInfo', JOBOBJECT_BASIC_ACCOUNTING_INFORMATION),
31 | ('IoInfo', IO_COUNTERS)]
32 |
33 | # see http://msdn.microsoft.com/en-us/library/ms684147%28VS.85%29.aspx
34 | class JOBOBJECT_BASIC_LIMIT_INFORMATION(Structure):
35 | _fields_ = [('PerProcessUserTimeLimit', LARGE_INTEGER),
36 | ('PerJobUserTimeLimit', LARGE_INTEGER),
37 | ('LimitFlags', DWORD),
38 | ('MinimumWorkingSetSize', SIZE_T),
39 | ('MaximumWorkingSetSize', SIZE_T),
40 | ('ActiveProcessLimit', DWORD),
41 | ('Affinity', ULONG_PTR),
42 | ('PriorityClass', DWORD),
43 | ('SchedulingClass', DWORD)
44 | ]
45 |
46 | # see http://msdn.microsoft.com/en-us/library/ms684156%28VS.85%29.aspx
47 | class JOBOBJECT_EXTENDED_LIMIT_INFORMATION(Structure):
48 | _fields_ = [('BasicLimitInformation', JOBOBJECT_BASIC_LIMIT_INFORMATION),
49 | ('IoInfo', IO_COUNTERS),
50 | ('ProcessMemoryLimit', SIZE_T),
51 | ('JobMemoryLimit', SIZE_T),
52 | ('PeakProcessMemoryUsed', SIZE_T),
53 | ('PeakJobMemoryUsed', SIZE_T)]
54 |
55 | # XXX Magical numbers like 8 should be documented
56 | JobObjectBasicAndIoAccountingInformation = 8
57 |
58 | # ...like magical number 9 comes from
59 | # http://community.flexerasoftware.com/archive/index.php?t-181670.html
60 | # I wish I had a more canonical source
61 | JobObjectExtendedLimitInformation = 9
62 |
63 | class JobObjectInfo(object):
64 | mapping = { 'JobObjectBasicAndIoAccountingInformation': 8,
65 | 'JobObjectExtendedLimitInformation': 9
66 | }
67 | structures = { 8: JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,
68 | 9: JOBOBJECT_EXTENDED_LIMIT_INFORMATION
69 | }
70 | def __init__(self, _class):
71 | if isinstance(_class, str):
72 | assert _class in self.mapping, 'Class should be one of %s; you gave %s' % (self.mapping, _class)
73 | _class = self.mapping[_class]
74 | assert _class in self.structures, 'Class should be one of %s; you gave %s' % (self.structures, _class)
75 | self.code = _class
76 | self.info = self.structures[_class]()
77 |
78 |
79 | QueryInformationJobObjectProto = WINFUNCTYPE(
80 | BOOL, # Return type
81 | HANDLE, # hJob
82 | DWORD, # JobObjectInfoClass
83 | LPVOID, # lpJobObjectInfo
84 | DWORD, # cbJobObjectInfoLength
85 | LPDWORD # lpReturnLength
86 | )
87 |
88 | QueryInformationJobObjectFlags = (
89 | (1, 'hJob'),
90 | (1, 'JobObjectInfoClass'),
91 | (1, 'lpJobObjectInfo'),
92 | (1, 'cbJobObjectInfoLength'),
93 | (1, 'lpReturnLength', None)
94 | )
95 |
96 | _QueryInformationJobObject = QueryInformationJobObjectProto(
97 | ('QueryInformationJobObject', windll.kernel32),
98 | QueryInformationJobObjectFlags
99 | )
100 |
101 | class SubscriptableReadOnlyStruct(object):
102 | def __init__(self, struct):
103 | self._struct = struct
104 |
105 | def _delegate(self, name):
106 | result = getattr(self._struct, name)
107 | if isinstance(result, Structure):
108 | return SubscriptableReadOnlyStruct(result)
109 | return result
110 |
111 | def __getitem__(self, name):
112 | match = [fname for fname, ftype in self._struct._fields_
113 | if fname == name]
114 | if match:
115 | return self._delegate(name)
116 | raise KeyError(name)
117 |
118 | def __getattr__(self, name):
119 | return self._delegate(name)
120 |
121 | def QueryInformationJobObject(hJob, JobObjectInfoClass):
122 | jobinfo = JobObjectInfo(JobObjectInfoClass)
123 | result = _QueryInformationJobObject(
124 | hJob=hJob,
125 | JobObjectInfoClass=jobinfo.code,
126 | lpJobObjectInfo=addressof(jobinfo.info),
127 | cbJobObjectInfoLength=sizeof(jobinfo.info)
128 | )
129 | if not result:
130 | raise WinError()
131 | return SubscriptableReadOnlyStruct(jobinfo.info)
132 |
133 | def test_qijo():
134 | from .killableprocess import Popen
135 |
136 | popen = Popen('c:\\windows\\notepad.exe')
137 |
138 | try:
139 | result = QueryInformationJobObject(0, 8)
140 | raise AssertionError('throw should occur')
141 | except WindowsError as e:
142 | pass
143 |
144 | try:
145 | result = QueryInformationJobObject(0, 1)
146 | raise AssertionError('throw should occur')
147 | except NotImplementedError as e:
148 | pass
149 |
150 | result = QueryInformationJobObject(popen._job, 8)
151 | if result['BasicInfo']['ActiveProcesses'] != 1:
152 | raise AssertionError('expected ActiveProcesses to be 1')
153 | popen.kill()
154 |
155 | result = QueryInformationJobObject(popen._job, 8)
156 | if result.BasicInfo.ActiveProcesses != 0:
157 | raise AssertionError('expected ActiveProcesses to be 0')
158 |
--------------------------------------------------------------------------------
/repls/sublimeutop_repl.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | from __future__ import absolute_import, print_function, division
3 |
4 | try:
5 | from queue import Queue
6 | except ImportError:
7 | from Queue import Queue
8 | from .subprocess_repl import SubprocessRepl
9 |
10 | class SublimeUTopRepl(SubprocessRepl):
11 | TYPE = "sublime_utop"
12 |
13 | def __init__(self, encoding, **kwds):
14 | super(SublimeUTopRepl, self).__init__(encoding, apiv2=True, **kwds)
15 |
16 | # Buffer for reassembling stanzas arrived from utop.
17 | self._buffer = b''
18 |
19 | # Phrase pending input with mapping of utop-lines to
20 | # SublimeREPL-view-lines.
21 | self._phrase = []
22 | self._phrase_line_begins = []
23 |
24 | # Completion state.
25 | self._completions = None
26 | self._completion_prefix = ""
27 | self._completion_queue = Queue()
28 |
29 | def autocomplete_available(self):
30 | return True
31 |
32 | def autocomplete_completions(self, whole_line, pos_in_line,
33 | prefix, whole_prefix, locations):
34 | self._completion_prefix = prefix
35 | self.write_command('complete', '', [whole_prefix])
36 |
37 | # This would block the UI. When REPL works correctly,
38 | # this blocks for less than 100ms.
39 | return [(x, x) for x in self._completion_queue.get(timeout=500)]
40 |
41 | #
42 | # USER INTERACTION LEVEL
43 | #
44 | # User interaction consists of visible artifacts (prompt, etc)
45 | # and input in form of complete expressions. History is handled
46 | # by SublimeREPL.
47 | #
48 |
49 | def compose_highlights(self, a, b):
50 | highlights = []
51 |
52 | # Highlight each fragment of line which lies in [a;b).
53 | for (line, loc) in zip(self._phrase, self._phrase_line_begins):
54 | # Does this line have any highlight?
55 | if a < len(line):
56 | # Yeah, does it end here?
57 | if b <= len(line):
58 | # Highlight the requested area and return.
59 | highlights.append((loc + a, loc + b))
60 | break
61 | else:
62 | # Highlight till the end of line.
63 | highlights.append((loc + a, loc + len(line)))
64 |
65 | # Shift the highlight region left by len(line) and
66 | # continue.
67 | a -= len(line) + 1
68 | b -= len(line) + 1
69 | # Always start from beginning of line for next lines.
70 | if a < 0:
71 | a = 0
72 |
73 | return [('highlight', x) for x in highlights]
74 |
75 | def read(self):
76 | stanza = self.read_stanza()
77 | if stanza is None:
78 | return None
79 |
80 | key, value = stanza
81 | if key == 'accept':
82 | packet = []
83 |
84 | if value != "":
85 | a, b = map(int, value.split(','))
86 | packet.extend(self.compose_highlights(a, b))
87 |
88 | # We've finished this phrase.
89 | self._phrase = []
90 | self._phrase_line_begins = []
91 |
92 | # Erase prompt. Accept is the first stanza we receive in
93 | # reply to input; immediately after it may follow stdout/stderr
94 | # and prompt stanzas in any order. To avoid garbled text,
95 | # we need to erase prompt before continuing.
96 | packet.append(('prompt', ''))
97 | packet.append(('output', '\n'))
98 | return packet
99 |
100 | elif key == 'stdout':
101 | return [('output', value + '\n')]
102 | elif key == 'stderr':
103 | return [('output', '! ' + value + '\n')]
104 |
105 | elif key == 'prompt':
106 | return [('prompt', '# ')]
107 | elif key == 'continue':
108 | return [('prompt', '\n ')]
109 |
110 | # Full completion reply is completion-start..completion*..completion-end.
111 | # Names are fully qualified, i.e. Thread.
112 | elif key == 'completion-start':
113 | self._completions = []
114 | return []
115 | elif key == 'completion':
116 | self._completions.append(value)
117 | return []
118 | elif key == 'completion-stop':
119 | self._completion_queue.put(self._completions)
120 | self._completions = None
121 | return []
122 |
123 | # Word completion reply is just completion-word stanza.
124 | # Names are partial, i.e. ead ([Thr]ead).
125 | elif key == 'completion-word':
126 | self._completion_queue.put([self._completion_prefix + value])
127 | return []
128 |
129 | # Stuff we don't care about: phrase-terminator.
130 | # Stuff we never receive: history-*.
131 | else:
132 | return []
133 |
134 | def write(self, expression, location=None):
135 | # If the phrase is incomplete, utop will not remember it, so
136 | # we need to account for it here. Also, Shift+Enter will add a literal
137 | # newline, which would otherwise break protocol.
138 | for line in expression.split('\n'):
139 | self._phrase.append(line)
140 | if location is not None:
141 | self._phrase_line_begins.append(location)
142 | location += len(line) + 1
143 |
144 | self.write_command('input', 'allow-incomplete', self._phrase)
145 |
146 | #
147 | # COMMAND LEVEL
148 | #
149 | # A command is a collection of stanzas: one begin stanza,
150 | # zero or more data stanzas, and one end stanza.
151 | #
152 |
153 | def write_command(self, command, options, data):
154 | self.write_stanza(command, options)
155 | for datum in data:
156 | self.write_stanza('data', datum)
157 | self.write_stanza('end')
158 |
159 | #
160 | # STANZA LEVEL
161 | #
162 | # A stanza is a statement of form "key:value\n".
163 | # Decoding and encoding is done on the stanza level.
164 | #
165 |
166 | def read_stanza(self):
167 | while True:
168 | try:
169 | stanza_end = self._buffer.index(b'\n')
170 | stanza = self.decoder.decode(self._buffer[:stanza_end])
171 | self._buffer = self._buffer[stanza_end+1:]
172 |
173 | colon = stanza.index(':')
174 | return stanza[:colon], stanza[colon+1:]
175 | except ValueError:
176 | bytes = self.read_bytes()
177 | if not bytes:
178 | return None
179 | else:
180 | self._buffer += bytes
181 |
182 | def write_stanza(self, key, value=''):
183 | (bytes, _) = self.encoder(key + ':' + value + '\n')
184 | self.write_bytes(bytes)
185 |
--------------------------------------------------------------------------------
/config/Io/Io.tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keyEquivalent
6 | ^~I
7 | name
8 | Io Repl
9 | patterns
10 |
11 |
12 | captures
13 |
14 | 1
15 |
16 | name
17 | meta.empty-parenthesis.io
18 |
19 |
20 | comment
21 | we match this to overload return inside () --Allan; scoping rules for what gets the scope have changed, so we now group the ) instead of the ( -- Rob
22 | match
23 | \((\))
24 |
25 |
26 | captures
27 |
28 | 1
29 |
30 | name
31 | meta.comma-parenthesis.io
32 |
33 |
34 | comment
35 | We want to do the same for ,) -- Seckar; same as above -- Rob
36 | match
37 | \,(\))
38 |
39 |
40 | match
41 | \b(if|ifTrue|ifFalse|ifTrueIfFalse|for|loop|reverseForeach|foreach|map|continue|break|while|do|return)\b
42 | name
43 | keyword.control.io
44 |
45 |
46 | begin
47 | /\*
48 | captures
49 |
50 | 0
51 |
52 | name
53 | punctuation.definition.comment.io
54 |
55 |
56 | end
57 | \*/
58 | name
59 | comment.block.io
60 |
61 |
62 | begin
63 | (^[ \t]+)?(?=//)
64 | beginCaptures
65 |
66 | 1
67 |
68 | name
69 | punctuation.whitespace.comment.leading.io
70 |
71 |
72 | end
73 | (?!\G)
74 | patterns
75 |
76 |
77 | begin
78 | //
79 | beginCaptures
80 |
81 | 0
82 |
83 | name
84 | punctuation.definition.comment.io
85 |
86 |
87 | end
88 | \n
89 | name
90 | comment.line.double-slash.io
91 |
92 |
93 |
94 |
95 | begin
96 | (^[ \t]+)?(?=#)
97 | beginCaptures
98 |
99 | 1
100 |
101 | name
102 | punctuation.whitespace.comment.leading.io
103 |
104 |
105 | end
106 | (?!\G)
107 | patterns
108 |
109 |
110 | begin
111 | #
112 | beginCaptures
113 |
114 | 0
115 |
116 | name
117 | punctuation.definition.comment.io
118 |
119 |
120 | end
121 | \n
122 | name
123 | comment.line.number-sign.io
124 |
125 |
126 |
127 |
128 | comment
129 | I wonder if some of this isn't variable.other.language? --Allan; scoping this as variable.language to match Objective-C's handling of 'self', which is inconsistent with C++'s handling of 'this' but perhaps intentionally so -- Rob
130 | match
131 | \b(self|sender|target|proto|protos|parent)\b
132 | name
133 | variable.language.io
134 |
135 |
136 | match
137 | <=|>=|=|:=|\*|\||\|\||\+|-|/|&|&&|>|<|\?|@|@@|\b(and|or)\b
138 | name
139 | keyword.operator.io
140 |
141 |
142 | match
143 | \bGL[\w_]+\b
144 | name
145 | constant.other.io
146 |
147 |
148 | match
149 | \b([A-Z](\w+)?)\b
150 | name
151 | support.class.io
152 |
153 |
154 | match
155 | \b(clone|call|init|method|list|vector|block|(\w+(?=\s*\()))\b
156 | name
157 | support.function.io
158 |
159 |
160 | match
161 | \b(gl(u|ut)?[A-Z]\w+)\b
162 | name
163 | support.function.open-gl.io
164 |
165 |
166 | begin
167 | """
168 | beginCaptures
169 |
170 | 0
171 |
172 | name
173 | punctuation.definition.string.begin.io
174 |
175 |
176 | end
177 | """
178 | endCaptures
179 |
180 | 0
181 |
182 | name
183 | punctuation.definition.string.end.io
184 |
185 |
186 | name
187 | string.quoted.triple.io
188 | patterns
189 |
190 |
191 | match
192 | \\.
193 | name
194 | constant.character.escape.io
195 |
196 |
197 |
198 |
199 | begin
200 | "
201 | beginCaptures
202 |
203 | 0
204 |
205 | name
206 | punctuation.definition.string.begin.io
207 |
208 |
209 | end
210 | "
211 | endCaptures
212 |
213 | 0
214 |
215 | name
216 | punctuation.definition.string.end.io
217 |
218 |
219 | name
220 | string.quoted.double.io
221 | patterns
222 |
223 |
224 | match
225 | \\.
226 | name
227 | constant.character.escape.io
228 |
229 |
230 |
231 |
232 | match
233 | \b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\b
234 | name
235 | constant.numeric.io
236 |
237 |
238 | match
239 | (Lobby)\b
240 | name
241 | variable.other.global.io
242 |
243 |
244 | match
245 | \b(TRUE|true|FALSE|false|NULL|null|Null|Nil|nil|YES|NO)\b
246 | name
247 | constant.language.io
248 |
249 |
250 | scopeName
251 | source.io
252 | uuid
253 | 52E416F3-9DF2-4579-8BC6-C54EBEF94423
254 |
255 |
256 |
--------------------------------------------------------------------------------
/lang_integration.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
2 | import sublime
3 | import sublime_plugin
4 |
5 | import re
6 | import os
7 | import glob
8 | import os.path
9 | import socket
10 | from functools import partial
11 | from contextlib import closing
12 |
13 | SETTINGS_FILE = "SublimeREPL.sublime-settings"
14 |
15 | class ClojureAutoTelnetRepl(sublime_plugin.WindowCommand):
16 | def is_running(self, port_str):
17 | """Check if port is open on localhost"""
18 | port = int(port_str)
19 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
20 | res = s.connect_ex(("127.0.0.1", port))
21 | s.close()
22 | return res == 0
23 |
24 | def choices(self):
25 | choices = []
26 | for folder in self.window.folders():
27 | proj_file = os.path.join(folder, "project.clj")
28 | try:
29 | with open(proj_file) as f:
30 | data = f.read()
31 | port_match = re.search(":repl-port\s+(\d{1,})", data)
32 | if not port_match:
33 | continue
34 | port = port_match.group(1)
35 | description = proj_file
36 | desc_match = re.search(r':description\s+"([^"]+)"', data)
37 | if desc_match:
38 | description = desc_match.group(1)
39 | if self.is_running(port):
40 | description += " (active)"
41 | else:
42 | description += " (not responding)"
43 | choices.append([description, port])
44 | except IOError as e:
45 | pass # just ignore it, no file or no access
46 |
47 | return choices + [["Custom telnet", "Pick your own telnet port number to Lein REPL"]]
48 |
49 | def run(self):
50 | choices = self.choices()
51 | if len(choices) == 1: #only custom telnet action
52 | self.on_done(choices, 0)
53 | else:
54 | on_done = partial(self.on_done, choices)
55 | self.window.show_quick_panel(self.choices(), on_done)
56 |
57 | def on_done(self, choices, index):
58 | if index == -1:
59 | return
60 | if index == len(choices) - 1:
61 | self.window.show_input_panel("Enter port number", "",
62 | self.open_telnet_repl,
63 | None, None)
64 | return
65 | self.open_telnet_repl(choices[index][1])
66 |
67 | def open_telnet_repl(self, port_str):
68 | try:
69 | port = int(port_str)
70 | except ValueError:
71 | return
72 | self.window.run_command("repl_open", {"type":"telnet", "encoding":"utf8", "host":"localhost", "port":port,
73 | "external_id":"clojure", "syntax":"Packages/Clojure/Clojure.tmLanguage"})
74 |
75 |
76 | def scan_for_virtualenvs(venv_paths):
77 | bin_dir = "Scripts" if os.name == "nt" else "bin"
78 | found_dirs = set()
79 | for venv_path in venv_paths:
80 | p = os.path.expanduser(venv_path)
81 | pattern = os.path.join(p, "*", bin_dir, "activate_this.py")
82 | found_dirs.update(list(map(os.path.dirname, glob.glob(pattern))))
83 | return sorted(found_dirs)
84 |
85 |
86 | class PythonVirtualenvRepl(sublime_plugin.WindowCommand):
87 | def _scan(self):
88 | venv_paths = sublime.load_settings(SETTINGS_FILE).get("python_virtualenv_paths", [])
89 | return scan_for_virtualenvs(venv_paths)
90 |
91 | def run_virtualenv(self, choices, index):
92 | if index == -1:
93 | return
94 | (name, directory) = choices[index]
95 | activate_file = os.path.join(directory, "activate_this.py")
96 | python_executable = os.path.join(directory, "python")
97 | path_separator = ":"
98 | if os.name == "nt":
99 | python_executable += ".exe" # ;-)
100 | path_separator = ";"
101 |
102 | self.window.run_command("repl_open",
103 | {
104 | "encoding":"utf8",
105 | "type": "subprocess",
106 | "autocomplete_server": True,
107 | "extend_env": {
108 | "PATH": directory + path_separator + "{PATH}",
109 | "SUBLIMEREPL_ACTIVATE_THIS": activate_file,
110 | "PYTHONIOENCODING": "utf-8"
111 | },
112 | "cmd": [python_executable, "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"],
113 | "cwd": "$file_path",
114 | "encoding": "utf8",
115 | "syntax": "Packages/Python/Python.tmLanguage",
116 | "external_id": "python"
117 | })
118 |
119 | def run(self):
120 | choices = self._scan()
121 | nice_choices = [[path.split(os.path.sep)[-2], path] for path in choices]
122 | self.window.show_quick_panel(nice_choices, partial(self.run_virtualenv, nice_choices))
123 |
124 |
125 | VENV_SCAN_CODE = """
126 | import os
127 | import glob
128 | import os.path
129 |
130 | venv_paths = channel.receive()
131 | bin_dir = "Scripts" if os.name == "nt" else "bin"
132 | found_dirs = set()
133 | for venv_path in venv_paths:
134 | p = os.path.expanduser(venv_path)
135 | pattern = os.path.join(p, "*", bin_dir, "activate_this.py")
136 | found_dirs.update(map(os.path.dirname, glob.glob(pattern)))
137 |
138 | channel.send(found_dirs)
139 | channel.close()
140 |
141 | """
142 |
143 | class ExecnetVirtualenvRepl(sublime_plugin.WindowCommand):
144 | def run(self):
145 | self.window.show_input_panel("SSH connection (eg. user@host)", "", self.on_ssh_select, None, None)
146 |
147 | def on_ssh_select(self, host_string):
148 | import execnet
149 | venv_paths = sublime.load_settings(SETTINGS_FILE).get("python_virtualenv_paths", [])
150 | try:
151 | gw = execnet.makegateway("ssh=" + host_string)
152 | ch = gw.remote_exec(VENV_SCAN_CODE)
153 | except Exception as e:
154 | sublime.error_message(repr(e))
155 | return
156 |
157 | with closing(ch):
158 | ch.send(venv_paths)
159 | directories = ch.receive(60)
160 | gw.exit()
161 |
162 | choices = [[host_string + ":" + path.split(os.path.sep)[-2], path] for path in sorted(directories)]
163 | nice_choices = [["w/o venv", "n/a"]] + choices
164 | self.window.show_quick_panel(nice_choices, partial(self.run_virtualenv, host_string, nice_choices))
165 |
166 | def run_virtualenv(self, host_string, nice_choices, index):
167 | if index == -1:
168 | return
169 | if index == 0:
170 | connection_string = "ssh={host}".format(host=host_string)
171 | ps1 = "({host}@) >>> ".format(host=host_string)
172 | activate_file = ""
173 | else:
174 | (name, directory) = nice_choices[index]
175 | activate_file = os.path.join(directory, "activate_this.py")
176 | python_file = os.path.join(directory, "python")
177 | ps1 = "({name}) >>> ".format(name=name, host=host_string)
178 | connection_string = "ssh={host}//env:PATH={dir}//python={python}".format(
179 | host=host_string,
180 | dir=directory,
181 | python=python_file
182 | )
183 |
184 | self.window.run_command("repl_open",
185 | {
186 | "type": "execnet_repl",
187 | "encoding": "utf8",
188 | "syntax": "Packages/Python/Python.tmLanguage",
189 | "connection_string": connection_string,
190 | "activate_file": activate_file,
191 | "ps1": ps1
192 | })
193 |
194 |
195 |
196 |
197 |
198 |
--------------------------------------------------------------------------------
/doc/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # SublimeREPL documentation build configuration file, created by
4 | # sphinx-quickstart on Sun Feb 26 16:38:41 2012.
5 | #
6 | # This file is execfile()d with the current directory set to its containing dir.
7 | #
8 | # Note that not all possible configuration values are present in this
9 | # autogenerated file.
10 | #
11 | # All configuration values have a default; values that are commented out
12 | # serve to show the default.
13 |
14 | import sys, os
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | #sys.path.insert(0, os.path.abspath('.'))
20 |
21 | # -- General configuration -----------------------------------------------------
22 |
23 | # If your documentation needs a minimal Sphinx version, state it here.
24 | #needs_sphinx = '1.0'
25 |
26 | # Add any Sphinx extension module names here, as strings. They can be extensions
27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28 | extensions = []
29 |
30 | # Add any paths that contain templates here, relative to this directory.
31 | templates_path = ['_templates']
32 |
33 | # The suffix of source filenames.
34 | source_suffix = '.rst'
35 |
36 | # The encoding of source files.
37 | #source_encoding = 'utf-8-sig'
38 |
39 | # The master toctree document.
40 | master_doc = 'index'
41 |
42 | # General information about the project.
43 | project = 'SublimeREPL'
44 | copyright = '2012, Wojciech Bederski'
45 |
46 | # The version info for the project you're documenting, acts as replacement for
47 | # |version| and |release|, also used in various other places throughout the
48 | # built documents.
49 | #
50 | # The short X.Y version.
51 | version = '1.0'
52 | # The full version, including alpha/beta/rc tags.
53 | release = '1.0.30'
54 |
55 | # The language for content autogenerated by Sphinx. Refer to documentation
56 | # for a list of supported languages.
57 | #language = None
58 |
59 | # There are two options for replacing |today|: either, you set today to some
60 | # non-false value, then it is used:
61 | #today = ''
62 | # Else, today_fmt is used as the format for a strftime call.
63 | #today_fmt = '%B %d, %Y'
64 |
65 | # List of patterns, relative to source directory, that match files and
66 | # directories to ignore when looking for source files.
67 | exclude_patterns = ['_build']
68 |
69 | # The reST default role (used for this markup: `text`) to use for all documents.
70 | #default_role = None
71 |
72 | # If true, '()' will be appended to :func: etc. cross-reference text.
73 | #add_function_parentheses = True
74 |
75 | # If true, the current module name will be prepended to all description
76 | # unit titles (such as .. function::).
77 | #add_module_names = True
78 |
79 | # If true, sectionauthor and moduleauthor directives will be shown in the
80 | # output. They are ignored by default.
81 | #show_authors = False
82 |
83 | # The name of the Pygments (syntax highlighting) style to use.
84 | pygments_style = 'sphinx'
85 |
86 | # A list of ignored prefixes for module index sorting.
87 | #modindex_common_prefix = []
88 |
89 |
90 | # -- Options for HTML output ---------------------------------------------------
91 |
92 | # The theme to use for HTML and HTML Help pages. See the documentation for
93 | # a list of builtin themes.
94 | html_theme = 'default'
95 |
96 | # Theme options are theme-specific and customize the look and feel of a theme
97 | # further. For a list of options available for each theme, see the
98 | # documentation.
99 | #html_theme_options = {}
100 |
101 | # Add any paths that contain custom themes here, relative to this directory.
102 | #html_theme_path = []
103 |
104 | # The name for this set of Sphinx documents. If None, it defaults to
105 | # " v documentation".
106 | #html_title = None
107 |
108 | # A shorter title for the navigation bar. Default is the same as html_title.
109 | #html_short_title = None
110 |
111 | # The name of an image file (relative to this directory) to place at the top
112 | # of the sidebar.
113 | #html_logo = None
114 |
115 | # The name of an image file (within the static path) to use as favicon of the
116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
117 | # pixels large.
118 | #html_favicon = None
119 |
120 | # Add any paths that contain custom static files (such as style sheets) here,
121 | # relative to this directory. They are copied after the builtin static files,
122 | # so a file named "default.css" will overwrite the builtin "default.css".
123 | html_static_path = ['_static']
124 |
125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
126 | # using the given strftime format.
127 | #html_last_updated_fmt = '%b %d, %Y'
128 |
129 | # If true, SmartyPants will be used to convert quotes and dashes to
130 | # typographically correct entities.
131 | #html_use_smartypants = True
132 |
133 | # Custom sidebar templates, maps document names to template names.
134 | #html_sidebars = {}
135 |
136 | # Additional templates that should be rendered to pages, maps page names to
137 | # template names.
138 | #html_additional_pages = {}
139 |
140 | # If false, no module index is generated.
141 | #html_domain_indices = True
142 |
143 | # If false, no index is generated.
144 | #html_use_index = True
145 |
146 | # If true, the index is split into individual pages for each letter.
147 | #html_split_index = False
148 |
149 | # If true, links to the reST sources are added to the pages.
150 | #html_show_sourcelink = True
151 |
152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
153 | #html_show_sphinx = True
154 |
155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
156 | #html_show_copyright = True
157 |
158 | # If true, an OpenSearch description file will be output, and all pages will
159 | # contain a tag referring to it. The value of this option must be the
160 | # base URL from which the finished HTML is served.
161 | #html_use_opensearch = ''
162 |
163 | # This is the file name suffix for HTML files (e.g. ".xhtml").
164 | #html_file_suffix = None
165 |
166 | # Output file base name for HTML help builder.
167 | htmlhelp_basename = 'SublimeREPLdoc'
168 |
169 |
170 | # -- Options for LaTeX output --------------------------------------------------
171 |
172 | latex_elements = {
173 | # The paper size ('letterpaper' or 'a4paper').
174 | #'papersize': 'letterpaper',
175 |
176 | # The font size ('10pt', '11pt' or '12pt').
177 | #'pointsize': '10pt',
178 |
179 | # Additional stuff for the LaTeX preamble.
180 | #'preamble': '',
181 | }
182 |
183 | # Grouping the document tree into LaTeX files. List of tuples
184 | # (source start file, target name, title, author, documentclass [howto/manual]).
185 | latex_documents = [
186 | ('index', 'SublimeREPL.tex', 'SublimeREPL Documentation',
187 | 'Wojciech Bederski', 'manual'),
188 | ]
189 |
190 | # The name of an image file (relative to this directory) to place at the top of
191 | # the title page.
192 | #latex_logo = None
193 |
194 | # For "manual" documents, if this is true, then toplevel headings are parts,
195 | # not chapters.
196 | #latex_use_parts = False
197 |
198 | # If true, show page references after internal links.
199 | #latex_show_pagerefs = False
200 |
201 | # If true, show URL addresses after external links.
202 | #latex_show_urls = False
203 |
204 | # Documents to append as an appendix to all manuals.
205 | #latex_appendices = []
206 |
207 | # If false, no module index is generated.
208 | #latex_domain_indices = True
209 |
210 |
211 | # -- Options for manual page output --------------------------------------------
212 |
213 | # One entry per manual page. List of tuples
214 | # (source start file, name, description, authors, manual section).
215 | man_pages = [
216 | ('index', 'sublimerepl', 'SublimeREPL Documentation',
217 | ['Wojciech Bederski'], 1)
218 | ]
219 |
220 | # If true, show URL addresses after external links.
221 | #man_show_urls = False
222 |
223 |
224 | # -- Options for Texinfo output ------------------------------------------------
225 |
226 | # Grouping the document tree into Texinfo files. List of tuples
227 | # (source start file, target name, title, author,
228 | # dir menu entry, description, category)
229 | texinfo_documents = [
230 | ('index', 'SublimeREPL', 'SublimeREPL Documentation',
231 | 'Wojciech Bederski', 'SublimeREPL', 'One line description of project.',
232 | 'Miscellaneous'),
233 | ]
234 |
235 | # Documents to append as an appendix to all manuals.
236 | #texinfo_appendices = []
237 |
238 | # If false, no module index is generated.
239 | #texinfo_domain_indices = True
240 |
241 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
242 | #texinfo_show_urls = 'footnote'
243 |
--------------------------------------------------------------------------------
/text_transfer.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals, print_function, division
2 |
3 | import re
4 | import sublime_plugin
5 | import sublime
6 | from collections import defaultdict
7 | import tempfile
8 | import binascii
9 |
10 | try:
11 | from .sublimerepl import manager, SETTINGS_FILE
12 | except (ImportError, ValueError):
13 | from sublimerepl import manager, SETTINGS_FILE
14 |
15 |
16 | def default_sender(repl, text, view=None, repl_view=None):
17 | if repl.apiv2:
18 | repl.write(text, location=repl_view.view.size() - len(text))
19 | else:
20 | repl.write(text)
21 |
22 | if view is None or not sublime.load_settings(SETTINGS_FILE).get('focus_view_on_transfer'):
23 | return
24 | active_window = sublime.active_window()
25 | active_view = active_window.active_view()
26 | target_view = repl_view.view
27 | if target_view == active_view:
28 | return #
29 | active_group = sublime.active_window().active_group()
30 | if target_view in active_window.views_in_group(active_group):
31 | return # same group, dont switch
32 | active_window.focus_view(target_view)
33 | active_window.focus_view(view)
34 |
35 |
36 | """Senders is a dict of functions used to transfer text to repl as a repl
37 | specific load_file action"""
38 | SENDERS = defaultdict(lambda: default_sender)
39 |
40 |
41 | def sender(external_id,):
42 | def wrap(func):
43 | SENDERS[external_id] = func
44 | return wrap
45 |
46 |
47 | @sender("coffee")
48 | def coffee(repl, text, view=None, repl_view=None):
49 | """
50 | use CoffeeScript multiline hack
51 | http://coffeescript.org/documentation/docs/repl.html
52 | """
53 | default_sender(repl, text.replace("\n", u'\uFF00') + "\n", view, repl_view)
54 |
55 | @sender("python")
56 | def python_sender(repl, text, view=None, repl_view=None):
57 | text_wo_encoding = re.sub(
58 | pattern=r"#.*coding[:=]\s*([-\w.]+)",
59 | repl="# ",
60 | string=text,
61 | count=1)
62 | code = binascii.hexlify(text_wo_encoding.encode("utf-8"))
63 | execute = ''.join([
64 | 'from binascii import unhexlify as __un; exec(compile(__un("',
65 | str(code.decode('ascii')),
66 | '").decode("utf-8"), "", "exec"))\n'
67 | ])
68 | return default_sender(repl, execute, view, repl_view)
69 |
70 |
71 | @sender("ruby")
72 | def ruby_sender(repl, text, view=None, repl_view=None):
73 | code = binascii.b2a_base64(text.encode("utf-8"))
74 | payload = "begin require 'base64'; eval(Base64.decode64('%s'), binding=TOPLEVEL_BINDING) end\n" % (code.decode("ascii"),)
75 | return default_sender(repl, payload, view, repl_view)
76 |
77 |
78 | # custom clojure sender that makes sure that all selections are
79 | # evaluated in the namespace declared by the file they are in
80 | @sender("clojure")
81 | def clojure_sender(repl, text, view, repl_view=None):
82 | # call (load-string) instead of just writing the string so
83 | # that syntax errors are caught and thrown back immediately.
84 | # also, escape backslashes and double-quotes
85 | text = '(load-string "' + text.strip().replace('\\', r'\\').replace('"', r'\"') + '")'
86 |
87 | # find the first non-commented statement from the start of the file
88 | namespacedecl = view.find(r"^[^;]*?\(", 0)
89 |
90 | # if it's a namespace declaration, go search for the namespace name
91 | if namespacedecl and view.scope_name(namespacedecl.end()-1).startswith("source.clojure meta.function.namespace.clojure"):
92 | namespacedecl = view.extract_scope(namespacedecl.end()-1)
93 |
94 | # we're looking for the first symbol within the declaration that
95 | # looks like a namespace and isn't metadata, a comment, etc.
96 | pos = namespacedecl.begin() + 3
97 | while pos < namespacedecl.end():
98 | # see http://clojure.org/reader for a description of valid
99 | # namespace names. the inital } or whitespace make sure we're
100 | # not matching on keywords etc.
101 | namespace = view.find(r"[\}\s][A-Za-z\_!\?\*\+\-][\w!\?\*\+\-:]*(\.[\w!\?\*\+\-:]+)*", pos)
102 |
103 | if not namespace:
104 | # couldn't find the namespace name within the declaration. suspicious.
105 | break
106 | elif view.scope_name(namespace.begin() + 1).startswith("source.clojure meta.function.namespace.clojure entity.name.namespace.clojure"):
107 | # looks alright, we've got our namespace!
108 | # switch to namespace before executing command
109 |
110 | # we could do this explicitly by calling (ns), (in-ns) etc:
111 | # text = "(ns " + view.substr(namespace)[1:] + ") " + text
112 | # but this would not only result in an extra return value
113 | # printed to the user, the repl would also remain in that
114 | # namespace after execution, so instead we do the same thing
115 | # that swank-clojure does:
116 | text = "(binding [*ns* (or (find-ns '" + view.substr(namespace)[1:] + ") (find-ns 'user))] " + text + ')'
117 | # i.e. we temporarily switch to the namespace if it has already
118 | # been created, otherwise we execute it in 'user. the most
119 | # elegant option for this would probably be:
120 | # text = "(binding [*ns* (create-ns '" + view.substr(namespace)[1:] + ")] " + text + ')'
121 | # but this can lead to problems because of newly created
122 | # namespaces not automatically referring to clojure.core
123 | # (see https://groups.google.com/forum/?fromgroups=#!topic/clojure/Th-Bqq68hfo)
124 | break
125 | else:
126 | # false alarm (metadata or a comment), keep looking
127 | pos = namespace.end()
128 | return default_sender(repl, text + repl.cmd_postfix, view, repl_view)
129 |
130 | class ReplViewWrite(sublime_plugin.TextCommand):
131 | def run(self, edit, external_id, text):
132 | for rv in manager.find_repl(external_id):
133 | rv.append_input_text(text)
134 | break # send to first repl found
135 | else:
136 | sublime.error_message("Cannot find REPL for '{0}'".format(external_id))
137 |
138 |
139 | class ReplSend(sublime_plugin.TextCommand):
140 | def run(self, edit, external_id, text, with_auto_postfix=True):
141 | for rv in manager.find_repl(external_id):
142 | if with_auto_postfix:
143 | text += rv.repl.cmd_postfix
144 | if sublime.load_settings(SETTINGS_FILE).get('show_transferred_text'):
145 | rv.append_input_text(text)
146 | rv.adjust_end()
147 | SENDERS[external_id](rv.repl, text, self.view, rv)
148 | break
149 | else:
150 | sublime.error_message("Cannot find REPL for '{}'".format(external_id))
151 |
152 |
153 | class ReplTransferCurrent(sublime_plugin.TextCommand):
154 | def run(self, edit, scope="selection", action="send"):
155 | text = ""
156 | if scope == "selection":
157 | text = self.selected_text()
158 | elif scope == "lines":
159 | text = self.selected_lines()
160 | elif scope == "function":
161 | text = self.selected_functions()
162 | elif scope == "block":
163 | text = self.selected_blocks()
164 | elif scope == "file":
165 | text = self.selected_file()
166 | cmd = "repl_" + action
167 | self.view.window().run_command(cmd, {"external_id": self.repl_external_id(), "text": text})
168 |
169 | def repl_external_id(self):
170 | return self.view.scope_name(0).split(" ")[0].split(".", 1)[1]
171 |
172 | def selected_text(self):
173 | v = self.view
174 | parts = [v.substr(region) for region in v.sel()]
175 | return "".join(parts)
176 |
177 | def selected_blocks(self):
178 | # TODO: Clojure only for now
179 | v = self.view
180 | strs = []
181 | old_sel = list(v.sel())
182 | v.run_command("expand_selection", {"to": "brackets"})
183 | v.run_command("expand_selection", {"to": "brackets"})
184 | for s in v.sel():
185 | strs.append(v.substr(s))
186 | v.sel().clear()
187 | for s in old_sel:
188 | v.sel().add(s)
189 | return "\n\n".join(strs)
190 |
191 | def selected_lines(self):
192 | v = self.view
193 | parts = []
194 | for sel in v.sel():
195 | for line in v.lines(sel):
196 | parts.append(v.substr(line))
197 | return "\n".join(parts)
198 |
199 | def selected_file(self):
200 | v = self.view
201 | return v.substr(sublime.Region(0, v.size()))
202 |
--------------------------------------------------------------------------------
/repls/subprocess_repl.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2011, Wojciech Bederski (wuub.net)
3 | # All rights reserved.
4 | # See LICENSE.txt for details.
5 | from __future__ import absolute_import, unicode_literals, print_function, division
6 |
7 | import subprocess
8 | import os
9 | import sys
10 | from .repl import Repl
11 | import signal
12 | from sublime import load_settings, error_message
13 | from .autocomplete_server import AutocompleteServer
14 | from .killableprocess import Popen
15 |
16 | PY3 = sys.version_info[0] == 3
17 |
18 | if os.name == 'posix':
19 | POSIX = True
20 | import fcntl
21 | import select
22 | else:
23 | POSIX = False
24 |
25 |
26 | class Unsupported(Exception):
27 | def __init__(self, msgs):
28 | super(Unsupported, self).__init__()
29 | self.msgs = msgs
30 |
31 | def __repr__(self):
32 | return "\n".join(self.msgs)
33 |
34 |
35 | def win_find_executable(executable, env):
36 | """Explicetely looks for executable in env["PATH"]"""
37 | if os.path.dirname(executable):
38 | return executable # executable is already absolute filepath
39 | path = env.get("PATH", "")
40 | pathext = env.get("PATHEXT") or ".EXE"
41 | dirs = path.split(os.path.pathsep)
42 | (base, ext) = os.path.splitext(executable)
43 | if ext:
44 | extensions = [ext]
45 | else:
46 | extensions = pathext.split(os.path.pathsep)
47 | for directory in dirs:
48 | for extension in extensions:
49 | filepath = os.path.join(directory, base + extension)
50 | if os.path.exists(filepath):
51 | return filepath
52 | return None
53 |
54 |
55 | class SubprocessRepl(Repl):
56 | TYPE = "subprocess"
57 |
58 | def __init__(self, encoding, cmd=None, env=None, cwd=None, extend_env=None, soft_quit="", autocomplete_server=False, **kwds):
59 | super(SubprocessRepl, self).__init__(encoding, **kwds)
60 | settings = load_settings('SublimeREPL.sublime-settings')
61 |
62 | if cmd[0] == "[unsupported]":
63 | raise Unsupported(cmd[1:])
64 |
65 | self._autocomplete_server = None
66 | if autocomplete_server:
67 | self._autocomplete_server = AutocompleteServer(self, settings.get("autocomplete_server_ip"))
68 | self._autocomplete_server.start()
69 |
70 | env = self.env(env, extend_env, settings)
71 | env[b"SUBLIMEREPL_AC_PORT"] = str(self.autocomplete_server_port()).encode("utf-8")
72 | env[b"SUBLIMEREPL_AC_IP"] = settings.get("autocomplete_server_ip").encode("utf-8")
73 |
74 | if PY3:
75 | strings_env = {}
76 | for k, v in env.items():
77 | strings_env[k.decode("utf-8")] = v.decode("utf-8")
78 | env = strings_env
79 |
80 | self._cmd = self.cmd(cmd, env)
81 | self._soft_quit = soft_quit
82 | self._killed = False
83 | self.popen = Popen(
84 | self._cmd,
85 | startupinfo=self.startupinfo(settings),
86 | creationflags=self.creationflags(settings),
87 | bufsize=1,
88 | cwd=self.cwd(cwd, settings),
89 | env=env,
90 | stderr=subprocess.STDOUT,
91 | stdin=subprocess.PIPE,
92 | stdout=subprocess.PIPE)
93 |
94 | if POSIX:
95 | flags = fcntl.fcntl(self.popen.stdout, fcntl.F_GETFL)
96 | fcntl.fcntl(self.popen.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
97 |
98 | def autocomplete_server_port(self):
99 | if not self._autocomplete_server:
100 | return None
101 | return self._autocomplete_server.port()
102 |
103 | def autocomplete_available(self):
104 | if not self._autocomplete_server:
105 | return False
106 | return self._autocomplete_server.connected()
107 |
108 | def autocomplete_completions(self, whole_line, pos_in_line, prefix, whole_prefix, locations):
109 | return self._autocomplete_server.complete(
110 | whole_line=whole_line,
111 | pos_in_line=pos_in_line,
112 | prefix=prefix,
113 | whole_prefix=whole_prefix,
114 | locations=locations,
115 | )
116 |
117 | def cmd(self, cmd, env):
118 | """On Linux and OSX just returns cmd, on windows it has to find
119 | executable in env because of this: http://bugs.python.org/issue8557"""
120 | if os.name != "nt":
121 | return cmd
122 | if isinstance(cmd, str):
123 | _cmd = [cmd]
124 | else:
125 | _cmd = cmd
126 | executable = win_find_executable(_cmd[0], env)
127 | if executable:
128 | _cmd[0] = executable
129 | return _cmd
130 |
131 | def cwd(self, cwd, settings):
132 | if cwd and os.path.exists(cwd):
133 | return cwd
134 | return None
135 |
136 | def getenv(self, settings):
137 | """Tries to get most appropriate environent, on windows
138 | it's os.environ.copy, but on other system's we'll
139 | try get values from login shell"""
140 |
141 | getenv_command = settings.get("getenv_command")
142 | if getenv_command and POSIX:
143 | try:
144 | output = subprocess.check_output(getenv_command)
145 | lines = output.decode("utf-8", errors="replace").splitlines()
146 | env = dict(line.split('=', 1) for line in lines)
147 | return env
148 | except:
149 | import traceback
150 | traceback.print_exc()
151 | error_message(
152 | "SublimeREPL: obtaining sane environment failed in getenv()\n"
153 | "Check console and 'getenv_command' setting \n"
154 | "WARN: Falling back to SublimeText environment")
155 |
156 | # Fallback to environ.copy() if not on POSIX or sane getenv failed
157 | return os.environ.copy()
158 |
159 | def env(self, env, extend_env, settings):
160 | updated_env = env if env else self.getenv(settings)
161 | default_extend_env = settings.get("default_extend_env")
162 | if default_extend_env:
163 | updated_env.update(self.interpolate_extend_env(updated_env, default_extend_env))
164 | if extend_env:
165 | updated_env.update(self.interpolate_extend_env(updated_env, extend_env))
166 |
167 | bytes_env = {}
168 | for k, v in list(updated_env.items()):
169 | try:
170 | enc_k = self.encoder(str(k))[0]
171 | enc_v = self.encoder(str(v))[0]
172 | except UnicodeDecodeError:
173 | continue #f*** it, we'll do it live
174 | else:
175 | bytes_env[enc_k] = enc_v
176 | return bytes_env
177 |
178 | def interpolate_extend_env(self, env, extend_env):
179 | """Interpolates (subst) values in extend_env.
180 | Mostly for path manipulation"""
181 | new_env = {}
182 | for key, val in list(extend_env.items()):
183 | new_env[key] = str(val).format(**env)
184 | return new_env
185 |
186 | def startupinfo(self, settings):
187 | startupinfo = None
188 | if os.name == 'nt':
189 | from .killableprocess import STARTUPINFO, STARTF_USESHOWWINDOW
190 | startupinfo = STARTUPINFO()
191 | startupinfo.dwFlags |= STARTF_USESHOWWINDOW
192 | startupinfo.wShowWindow |= 1 # SW_SHOWNORMAL
193 | return startupinfo
194 |
195 | def creationflags(self, settings):
196 | creationflags = 0
197 | if os.name == "nt":
198 | creationflags = 0x8000000 # CREATE_NO_WINDOW
199 | return creationflags
200 |
201 | def name(self):
202 | if self.external_id:
203 | return self.external_id
204 | if isinstance(self._cmd, str):
205 | return self._cmd
206 | return " ".join([str(x) for x in self._cmd])
207 |
208 | def is_alive(self):
209 | return self.popen.poll() is None
210 |
211 | def read_bytes(self):
212 | out = self.popen.stdout
213 | if POSIX:
214 | while True:
215 | i, _, _ = select.select([out], [], [])
216 | if i:
217 | return out.read(4096)
218 | else:
219 | # this is windows specific problem, that you cannot tell if there
220 | # are more bytes ready, so we read only 1 at a times
221 |
222 | while True:
223 | byte = self.popen.stdout.read(1)
224 | if byte == b'\r':
225 | # f'in HACK, for \r\n -> \n translation on windows
226 | # I tried universal_endlines but it was pain and misery! :'(
227 | continue
228 | return byte
229 |
230 |
231 |
232 | def write_bytes(self, bytes):
233 | si = self.popen.stdin
234 | si.write(bytes)
235 | si.flush()
236 |
237 | def kill(self):
238 | self._killed = True
239 | self.write(self._soft_quit)
240 | self.popen.kill()
241 |
242 | def available_signals(self):
243 | signals = {}
244 | for k, v in list(signal.__dict__.items()):
245 | if not k.startswith("SIG"):
246 | continue
247 | signals[k] = v
248 | return signals
249 |
250 | def send_signal(self, sig):
251 | if sig == signal.SIGTERM:
252 | self._killed = True
253 | if self.is_alive():
254 | self.popen.send_signal(sig)
255 |
256 |
--------------------------------------------------------------------------------