├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ └── test.yml
├── .gitignore
├── CHANGELOG
├── Eask
├── LICENSE
├── Makefile
├── README.md
├── example
└── quickrun_conf.el
├── quickrun.el
├── sample
├── Sample.java
├── sample-fail-colorize.coffee
├── sample.R
├── sample.awk
├── sample.bash
├── sample.c
├── sample.clj
├── sample.coffee
├── sample.cpp
├── sample.cs
├── sample.d
├── sample.dart
├── sample.el
├── sample.erl
├── sample.ex
├── sample.f95
├── sample.fish
├── sample.fsx
├── sample.go
├── sample.groovy
├── sample.haml
├── sample.hs
├── sample.io
├── sample.jl
├── sample.jsx
├── sample.less
├── sample.lisp
├── sample.lua
├── sample.m
├── sample.md
├── sample.ml
├── sample.nim
├── sample.php
├── sample.pl
├── sample.pl6
├── sample.plt
├── sample.pod
├── sample.py
├── sample.rb
├── sample.rkt
├── sample.rs
├── sample.sass
├── sample.scala
├── sample.scm
├── sample.sh
├── sample.swift
├── sample.t
├── sample.tcl
├── sample.ts
├── sample_as_function.pl
├── sample_buffer_local_var.c
├── sample_buffer_local_var2.pl
├── sample_c11.cpp
├── sample_color.pl
├── sample_compile_error.c
├── sample_endless_loop.bash
├── sample_interactive.c
├── sample_jrunscript.js
├── sample_js.js
├── sample_node.js
├── sample_noshebang.pl
├── sample_outputter_browser.pl
├── sample_outputter_buffer.pl
├── sample_outputter_file.pl
├── sample_outputter_multi.pl
├── sample_outputter_null.pl
├── sample_outputter_variable.pl
├── sample_set_default_directory.pl
├── sample_spec.rb
├── sample_timeout.c
├── sample_timeout.pl
├── sample_user_defined.cpp
├── sample_utf8_jp.scala
├── sample_with_arg.c
├── sample_with_arg.pl
└── sample_write_stderr.pl
└── test
└── test-quickrun.el
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [tarsius, jcs090218]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # replace with a single OpenCollective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: github-actions
4 | directory: /
5 | schedule:
6 | interval: daily
7 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | workflow_dispatch:
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | jobs:
15 | test:
16 | runs-on: ${{ matrix.os }}
17 | continue-on-error: ${{ matrix.experimental }}
18 | strategy:
19 | matrix:
20 | os: [ubuntu-latest, macos-latest, windows-latest]
21 | emacs-version:
22 | - 27.2
23 | - 28.2
24 | - 29.4
25 | - 30.1
26 | experimental: [false]
27 | include:
28 | - os: ubuntu-latest
29 | emacs-version: snapshot
30 | experimental: true
31 | - os: macos-latest
32 | emacs-version: snapshot
33 | experimental: true
34 | - os: windows-latest
35 | emacs-version: snapshot
36 | experimental: true
37 | exclude:
38 | - os: macos-latest
39 | emacs-version: 27.2
40 |
41 | steps:
42 | - uses: actions/checkout@v4
43 |
44 | - uses: jcs090218/setup-emacs@master
45 | with:
46 | version: ${{ matrix.emacs-version }}
47 |
48 | - uses: emacs-eask/setup-eask@master
49 | with:
50 | version: 'snapshot'
51 |
52 | - name: Run tests
53 | run:
54 | make ci
55 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.cask/
2 | /.eask
3 | /dist
4 | *.elc
5 |
6 | # local tests
7 | /_test
8 |
9 | # OS generated
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | Revision history for quickrun.el
2 |
3 | Version 2.3.1 N/A jcs090218
4 | - Support Deno (b8a9b716a8414c98d3a1ce9267c47c5dbbc7f67b)
5 | - Support Nix (#152)
6 | - feat: Add header and footer messages with exit code (#157)
7 |
8 | Version 2.2.8 2017/01/14 syohex
9 | - Support julia (#77)
10 | - Support gnuplot (#78)
11 | - Support racket (#81)
12 | - Fix not focus window case (#85)
13 | - Drop older Emacs support for maintenance
14 |
15 | Version 2.2.7 2016/02/16 syohex
16 | - Support Open source Swift (#68)
17 | - Fix nim issue (#71)
18 | - Fix ansi color sequence handling issue at error (#72)
19 | - Support nimscript (#73)
20 |
21 | Version 2.2.6 2015/08/08 syohex
22 | - Support perl6
23 |
24 | Version 2.2.5 2015/08/08 syohex
25 | - Support fish script
26 | - Improve quickrun-shell behavior (#62, #63)
27 | - Fix recentering issue (#61)
28 |
29 | Version 2.2.4 2015/07/10 syohex
30 | - Fix quickrun shell behavior
31 | - Implement autorun mode (#54)
32 | - Improve helm-quickrun history
33 | - Add option for focusing popup buffer
34 | - Add format place folder '%S'
35 |
36 | Version 2.2.3 2015/01/29 syohex
37 | - Support nim programming language
38 |
39 | Version 2.2.2 2015/01/29 syohex
40 | - Add parameter for whether using temporary file
41 | - Fix scrolling issue
42 |
43 | Version 2.2.1 2014/10/16 syohex
44 | - Fix #41
45 | Improve for users which set scroll-step other than 0.
46 |
47 | Version 2.2.0 2014/10/16 syohex
48 | - Drop Emacs 23 support
49 |
50 | Version 2.1.1 2014/10/16 tmalsburg
51 | - Support R programming language
52 |
53 | Version 2.1.0 2014/09/28 syohex
54 | - Update swift configuration for newer Xcode
55 |
56 | Version 2.0.9 2014/08/24 syohex
57 | - Fix Fortran file extention regexp
58 | - Improve F#
59 |
60 | Version 2.0.8 2014/08/21 syohex
61 | - Support F# programming language
62 |
63 | Version 2.0.7 2014/08/17 syohex
64 | - Support ATS programming language
65 | (Thanks murasesyuka)
66 |
67 | Version 2.0.6 2014/07/15 syohex
68 | - Fix for Apple Swift language
69 |
70 | Version 2.0.5 2014/07/07 syohex
71 | - Enable compilation-mode if errors are occurred
72 | - Support Tramp
73 |
74 | Version 2.0.4 2014/06/27 syohex
75 | - Add helm actions
76 | - run-with-arg
77 | - region execution
78 |
79 | Version 2.0.3 2014/06/13 syohex
80 | - Improve using stdin input
81 | - Fix documentation
82 | (Thanks pogin503)
83 |
84 | Version 2.0.2 2014/05/03 syohex
85 | - Improve using stdin input
86 |
87 | Version 2.0.1 2014/04/09 syohex
88 | - Fix typescript for version 1.0
89 |
90 | Version 2.0.0 2014/03/21 syohex
91 | - Support C#(mono)
92 |
93 | Version 1.9.9 2014/02/28 syohex
94 | - Support Tcl
95 |
96 | Version 1.9.8 2014/01/15 syohex
97 | - Support stdin file
98 |
99 | Version 1.9.7 2013/12/07 syohex
100 | - Apply colorizing if command is failed
101 | This is useful for color error message such as coffee-script
102 |
103 | Version 1.9.6 2013/11/04 syohex
104 | - Exec 'go test' when file is go test file
105 | - Fix outputter issue
106 |
107 | Version 1.9.5 2013/10/29 syohex
108 | - Add history feature for helm-quickrun
109 |
110 | Version 1.9.4 2013/10/10 syohex
111 | - Set proper file encoding for temporary file
112 | (Thanks Dewdrops !!)
113 |
114 | Version 1.9.3 2013/09/15 syohex
115 | - Improve 'q' behavior in quickrun buffer
116 | Don't use register function
117 |
118 | Version 1.9.2 2013/09/09 syohex
119 | - Add history variable for 'quickrun-with-arg'
120 |
121 | Version 1.9.1 2013/09/08 syohex
122 | - Improve 'q' behavior on quickrun buffer
123 |
124 | Version 1.9.0 2013/07/30 syohex
125 | - Support quickrun-compile-only for Go language
126 |
127 | Version 1.8.9 2013/07/02 syohex
128 | - Fix overwriting outputter issue
129 | - deactive-mark after quickrun-region
130 |
131 | Version 1.8.8 2013/06/24 syohex
132 | - Support mruby(Thanks to murasesyuka)
133 |
134 | Version 1.8.7 2013/06/10 syohex
135 | - Support :compile-conf parameter
136 |
137 | Version 1.8.6 2013/04/07 syohex
138 | - Fix for warnings of byte compile
139 |
140 | Version 1.8.5 2013/04/06 syohex
141 | - Change order of c and c++ compiler on MacOSX
142 |
143 | Version 1.8.4 2013/03/12 syohex
144 | - Fix for setting process-connection-type
145 | - Implement command which kills process
146 |
147 | Version 1.8.3 2013/03/11 syohex
148 | - Enable quickrun/mode if command is failed
149 |
150 | Version 1.8.2 2013/02/24 syohex
151 | - Add actions of helm source
152 | - refactoring for function naming
153 |
154 | Version 1.8.1 2013/02/20 syohex
155 | - Improve error handling
156 |
157 | Version 1.8.0 2013/02/20 syohex
158 | - Implement quickrun-replace-region
159 | - Refactoring
160 |
161 | Version 1.7.8 2013/02/06 syohex
162 | - Refactoring
163 |
164 | Version 1.7.7 2013/02/01 syohex
165 | - Fixed for warnings of byte-compile
166 |
167 | Version 1.7.6 2012/11/28 syohex
168 | - Remove all 'go' command configuration and add new one
169 | - Add hook 'quickrun-after-run-hook'
170 |
171 | Version 1.7.5 2012/11/14 syohex
172 | - Specify compiling language for GCC, Clang, Visual C++
173 | - Fix problem of buffer execution
174 |
175 | Version 1.7.4 2012/11/11 syohex
176 | - Support buffer execution
177 | Which has no relationship with file, such as *scratch* buffer
178 |
179 | Version 1.7.3 2012/10/28 syohex
180 | - Support override existing command
181 |
182 | Version 1.7.2 2012/10/12 syohex
183 | - Support HAML
184 |
185 | Version 1.7.1 2012/10/02 syohex
186 | - Support TypeScript
187 |
188 | Version 1.7 2012/08/31 syohex
189 | Thanks to rolandwalker
190 | - add autoload pragma to interactive functions
191 | - quickrun with C-u C-u prefix behaves same as quickrun-compile-only
192 |
193 | Version 1.6 2012/08/13 syohex
194 | - Implement quickrun-shell(Thanks to sza1991 for nice idea)
195 | - Deprecated quickrun-with-input-file(use quickrun shell instead of it)
196 | - Implement quickrun-mode in *quickrun* buffer.
197 | - delete window with 'q' key
198 |
199 | Version 1.5 2012/07/22 syohex
200 | - Rename quickrun parameter argument.
201 |
202 | Version 1.4 2012/07/22 syohex
203 | - Fixed for specified lambda to ':exec' parameter
204 |
205 | Version 1.3 2012/07/22 syohex
206 | - Support ':default-directory' parameter
207 | - Modify `quickrun' for using from other functions.
208 |
209 | Version 1.2 2012/07/07 syohex
210 | - Add helm-quickrun which is quickrun helm interface
211 |
212 | Version 1.1 2012/06/13 syohex
213 | - Support JSX and fortran(gfortran).
214 | - Support gccgo for golang
215 |
216 | Version 1.0 2012/04/30 syohex
217 | - Fixed PHP CR problem(Thanks to mat)
218 |
219 | Version 0.9 2012/04/08 syohex
220 | - Fix problem of not removing temporary file on Windows.
221 |
222 | Version 0.8 2012/03/19 syohex
223 | - Support Dart and Elixir
224 |
225 | Version 0.7 2012/02/14 syohex
226 | - Support Mozilla Rust language(Thanks to koko1000ban).
227 |
228 | Version 0.6 2012/02/14 syohex
229 | - Implement 'multi' outputter.
230 | - Change outputter:buffer behavior, not popup-buffer.
231 |
232 | Version 0.5 2012/02/08 syohex
233 | - Add quickrun group and modify global variable with `customize'
234 |
235 | Version 0.4 2012/01/18 syohex
236 | - Fix command-alist of emacs lisp and update its sample
237 | - Fix case of that scroll-conservatively is not zero.
238 |
239 | Version 0.3 2012/01/12 syohex
240 | - Support command line arguments that contain spaces or tabs
241 | - Add Common Lisp command-alist(ccl and sbcl)
242 |
243 | Version 0.2 2012/01/06 syohex
244 | - Fix for Windows(Thanks to leoncamel)
245 |
246 | Version 0.1 2011/12/31 syohex
247 | - init version
248 |
--------------------------------------------------------------------------------
/Eask:
--------------------------------------------------------------------------------
1 | ;; -*- mode: eask; lexical-binding: t -*-
2 |
3 | (package "quickrun"
4 | "2.3.1"
5 | "Run commands quickly")
6 |
7 | (website-url "https://github.com/emacsorphanage/quickrun")
8 | (keywords "tools")
9 |
10 | (package-file "quickrun.el")
11 |
12 | (script "test" "echo \"Error: no test specified\" && exit 1")
13 |
14 | (source 'gnu)
15 | (source 'melpa)
16 |
17 | (depends-on "emacs" "26.1")
18 | (depends-on "ht")
19 |
20 | (development
21 | (depends-on "helm")
22 | (depends-on "ert-runner"))
23 |
24 | (setq network-security-level 'low) ; see https://github.com/jcs090218/setup-emacs-windows/issues/156#issuecomment-932956432
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | EMACS ?= emacs
2 | EASK ?= eask
3 |
4 | .PHONY: clean checkdoc lint package install compile test
5 |
6 | ci: clean package install compile
7 |
8 | package:
9 | @echo "Packaging..."
10 | $(EASK) package
11 |
12 | install:
13 | @echo "Installing..."
14 | $(EASK) install
15 |
16 | compile:
17 | @echo "Compiling..."
18 | $(EASK) compile
19 |
20 | test:
21 | @echo "Testing..."
22 | $(EASK) test ert ./test/*.el
23 |
24 | checkdoc:
25 | @echo "Run checkdoc..."
26 | $(EASK) lint checkdoc
27 |
28 | lint:
29 | @echo "Run package-lint..."
30 | $(EASK) lint package
31 |
32 | clean:
33 | $(EASK) clean all
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [![melpa badge][melpa-badge]][melpa-link]
2 | [![melpa stable badge][melpa-stable-badge]][melpa-stable-link]
3 | [![jcs-elpa badge][jcs-elpa-badge]][jcs-elpa-link]
4 |
5 | # quickrun.el
6 |
7 | ## Introduction
8 |
9 | **quickrun.el** is Emacs port of [quickrun.vim](https://github.com/thinca/vim-quickrun).
10 |
11 | [](https://github.com/emacsorphanage/quickrun/actions/workflows/test.yml)
12 |
13 | `quickrun.el` is a extension to execute editing buffer.
14 | `quickrun.el` is similar to executable-interpret, but `quickrun.el` provides more convenient
15 | commands. `quickrun.el` execute not only script languages(Perl, Ruby, Python etc), but also
16 | compiling languages(C, C++, Go, Java etc) and markup language.
17 |
18 | ## Requirements
19 |
20 | * Emacs `26.1` or higher.
21 |
22 | ## Installation
23 |
24 | You can install `quickrun.el` from [MELPA](https://melpa.org/) with package.el.
25 |
26 | Or install directly:
27 |
28 | ```
29 | $ cd load-path-dir
30 | $ wget https://raw.githubusercontent.com/syohex/emacs-quickrun/master/quickrun.el
31 | ```
32 |
33 | After Installation add following to your configuration file(~/.emacs.d/init.el, ~/.emacs etc)
34 |
35 | ```lisp
36 | (require 'quickrun)
37 | ```
38 |
39 | ## Support Programming Languages
40 |
41 | `quickrun.el` supports following programming languages and markup languages
42 | as default. But you can register your own command and apply other languages.
43 |
44 | **Programming Language(commands used)**
45 |
46 | * Assembly Language (`nasm`, `masm`)
47 | * Applescript (`osascript`)
48 | * C (`gcc` / `clang` / `Visual C++`)
49 | * C++ (`g++` / `clang++` / `Visual C++`)
50 | * C# (`dotnet` / `mono`)
51 | * Objective-C (gcc -objc)
52 | * D Language (`dmd`)
53 | * Fortran (`gfortran`)
54 | * Java (`javac` / `java`)
55 | * Perl (`perl`)
56 | * Perl6 (`perl6`)
57 | * Ruby (`ruby` / `mruby`)
58 | * Python (`python`)
59 | * PHP (`php`)
60 | * Emacs Lisp (`elisp`)
61 | * Scheme (`gosh`)
62 | * Smalltalk (`gst`)
63 | * Racket (`racket`)
64 | * Common Lisp (`clisp` / `sbcl` / `ccl`)
65 | * Clojure (`jark` / `clj-env-dir`)
66 | * Javascript (`node` / `v8` / `js` / `jrunscript` / `cscript` / `deno`)
67 | * Coffee Script (`coffee`)
68 | * JSX (`jsx`)
69 | * Markdown (`Markdown.pl` / `bluecloth` / `kramdown` / `pandoc` / `redcarpet`)
70 | * Haskell (`runghc`)
71 | * Go Language (`go` / `gccgo`)
72 | * Io (`io`)
73 | * Lua (`lua`)
74 | * Groovy (`groovy`)
75 | * Scala (`scala`) **Please use UTF-8 encoding**
76 | * HAML (`haml`)
77 | * SASS (`sass`)
78 | * LESS (`lessc`)
79 | * Erlang (`escript`)
80 | * OCaml (`ocamlc`)
81 | * F# (`fsharpc`)
82 | * ShellScript (shebang's shell)
83 | * AWK (`awk`)
84 | * Rust (`rustc`)
85 | * Dart (`dart`)
86 | * Elixir (`elixir`)
87 | * TypeScript (`tsc`)
88 | * Tcl (`tclsh`)
89 | * Swift (`swift`, `xcrun`)
90 | * ATS2 (`patscc`)
91 | * R (`Rscript`)
92 | * Nim/NimScript (`nim`)
93 | * Julia (`julia`)
94 | * Gnuplot (`gnuplot`)
95 | * Kotlin (`kotlin`)
96 | * Crystal (`crystal`)
97 | * V (`v`)
98 | * Zig (`zig`)
99 | * Nix (`nix`)
100 |
101 | See also `quickrun--support-languages` global variable.
102 |
103 | ## Basic Usage
104 |
105 | #### `quickrun`
106 |
107 | Execute current buffer. If `quickrun.el` does not find command-key,
108 | then `quickrun.el` asks you command-key(You always input command
109 | if you use `C-u` prefix key)
110 |
111 | #### `quickrun-select`
112 |
113 | Like `quickrun` command but select the backend before the execution.
114 |
115 | #### `quickrun-region`
116 |
117 | Execute region. (Java is not supported)
118 |
119 | #### `quickrun-with-arg`
120 |
121 | Execute current buffer with arguments.
122 | `quickrun.el` asks you command line argument
123 |
124 | #### `quickrun-shell`
125 |
126 | Execute current buffer in eshell for interactive command such as program
127 | which reads input from STDIN.
128 |
129 | #### `quickrun-compile-only`
130 |
131 | Compile current buffer with compile.el framework, not execute.
132 | quickrun with `C-u C-u` prefix behaves same as quickrun-compile-only.
133 |
134 | #### `quickrun-compile-only-select`
135 |
136 | Like `quickrun-compile-only` command but select the backend before the execution.
137 |
138 | #### `quickrun-replace-region`
139 |
140 | Replace region of code with its output.
141 |
142 | ### `quickrun-autorun-mode`
143 |
144 | Minor mode which executes `quickrun` after saving buffer.
145 |
146 | #### `helm-quickrun`
147 |
148 | `M-x quickrun` with helm interface
149 |
150 | #### `anything-quickrun`
151 |
152 | `M-x quickrun` with anything interface
153 |
154 | ## Note
155 |
156 | If quickrun returns `command not found`, please check `(executable-find "THE_COMMAND_NAME")` [for example `(executable-find "gnuplot")`] .
157 | If this returns `nil`, I strongly recommend you use https://github.com/purcell/exec-path-from-shell
158 |
159 | ## Send File to STDIN
160 |
161 | If `executed_file.qrinput`(like `foo.c.qrinput`) is existed in directory same as executed
162 | buffer file, `quickrun.el` sends its content to stdin of executed program. Please set
163 | `quickrun-input-file-extension` to `nil` If you want to disable this feature.
164 |
165 | ## Customize
166 |
167 | ### `quickrun-focus-p`(Default: `t`)
168 |
169 | If this value is `nil`, quickrun.el does not move focus to output buffer.
170 |
171 | ### `quickrun-truncate-lines`(Default: `t`)
172 |
173 | The `truncate-lines' value for `*quickrun*` buffer.
174 |
175 | ## User Defined Command
176 |
177 | You can add your own command or override existsing command by `quickrun-add-command` as below.
178 |
179 | ```lisp
180 | ;; Use this parameter as C++ default
181 | (quickrun-add-command "c++/c1z"
182 | '((:command . "g++")
183 | (:exec . ("%c -std=c++1z %o -o %e %s"
184 | "%e %a"))
185 | (:remove . ("%e")))
186 | :default "c++")
187 |
188 | ;; Use this parameter in pod-mode
189 | (quickrun-add-command "pod"
190 | '((:command . "perldoc")
191 | (:exec . "%c -T -F %s"))
192 | :mode 'pod-mode)
193 |
194 | ;; You can override existing command
195 | (quickrun-add-command "c/gcc"
196 | '((:exec . ("%c -std=c++1z %o -o %e %s"
197 | "%e %a")))
198 | :override t)
199 | ```
200 |
201 | First argument of `quickrun-add-command` is command key. Second argument of it is
202 | command parameter, which is described laster. `quickrun-add-command` also takes
203 | key parameters, `:default`, `:mode`, `:override`.
204 |
205 | | Argument | Description |
206 | |:-----------------|:------------------------------------------------------------|
207 | | `:default` lang | Use this command parameter as default in specified language |
208 | | `:mode` mode | this command parameter in specified mode |
209 | | `:override` bool | Override existing parameter with specified parameter |
210 |
211 | ### Command Parameter
212 |
213 | Command alist has following parameters,
214 |
215 | #### `:command`(mandatory parameter)
216 |
217 | Command name. `%c` is expanded into this value.
218 |
219 | #### `:cmdopt`(optional)
220 |
221 | Command(`:command`) option. `%o` is expanded into this value.
222 |
223 | #### `:exec`
224 |
225 | Executed commands. You can also set command list parameter.
226 | If you set list parameter, `quickrun.el` executes command
227 | list in order.
228 |
229 | If this parameter is omitted, `quickrun.el` use default execute
230 | command template "%c %o %s %a".
231 |
232 | #### `:timeout`(optional)
233 |
234 | Timeout in seconds for the process spawn by the command. This value
235 | takes precedence over the `quickrun-timeout-seconds` custom variable.
236 |
237 | #### `:compile-only`
238 |
239 | Command exected by `quickrun-compile-only`. This option is used for
240 | syntax check or converting another language(e.g. CoffeeScript => JavaScript).
241 |
242 | ### `:compile-conf`
243 |
244 | Configuration of `quickrun-compile-only`. This parameter must be alist.
245 |
246 | #### `:remove`
247 |
248 | Remove files after executing.
249 | If command create some intermediate files, you should set this
250 | parameter. :remove value is atom or list.
251 |
252 | #### `:outputter`
253 |
254 | Please see Outputter section.
255 |
256 | #### `:default-directory`
257 |
258 | Directory where commands are executed.
259 |
260 | #### `:tempfile`
261 |
262 | Use temporary file or not. `quickrun.el` uses temporary file
263 | if you omit this parameter.
264 |
265 | NOTE: If you set this parameter, you cannot use `quickrun-region`.
266 |
267 | #### `:description`
268 |
269 | Description of this command. This parameter is used in
270 | `helm-quickrun` or `anything-quickrun`
271 |
272 | ### Placeholders
273 |
274 | You can use following placeholders in command parameter
275 |
276 | | Placeholder | Expanded |
277 | |:-----------:|:----------------------------------------------|
278 | | `%c` | Command |
279 | | `%o` | Command line option |
280 | | `%s` | Source(absolute path) |
281 | | `%a` | Script's arguments |
282 | | `%n` | Source without extension(absolute path) |
283 | | `%N` | Source without extension(nondirectory) |
284 | | `%d` | Directory name of Source(absolute path) |
285 | | `%e` | Source with executable suffix(absolute path) |
286 | | `%E` | Source with executable suffix(nondirectory) |
287 |
288 | Source file name(`%s`, `%n` etc) is not original file name except
289 | Java language. Because `quickrun.el` copys source file to temporary
290 | file firstly.
291 |
292 | ## Change Default Command
293 |
294 | `quickrun-set-default` changes default command in language that is registerd
295 | multiple command parameters(like c, c++,Javascript).
296 |
297 | ```lisp
298 | (quickrun-set-default "c" "c/clang")
299 | ```
300 |
301 | This means that quickrun uses "c/clang" for C files.
302 |
303 | ## Timeout Seconds
304 |
305 | `quickrun.el` kills process if program run over 10 seconds as default.
306 | This avoids infinite loop program or endless program by some mistakes.
307 | You control timeout second to set `quickrun-timeout-seconds`.
308 | This feature is disabled if `quickrun-timeout-seconds` is `nil`. The
309 | timeout can also be set per command with the `:timeout` parameter.
310 | (You can also kill process by `C-c C-c` in quickrun buffer)
311 |
312 | ## Key bindings in quickrun buffer
313 |
314 | | Key | Command |
315 | |:---------:|:-----------------------|
316 | | `q` | Close quickrun window |
317 | | `C-c C-c` | Kill quickrun process |
318 |
319 | ## Buffer Local Variables
320 |
321 | Buffer local variables is priority to default parameters.
322 |
323 | #### `quickrun-option-cmd-alist`
324 |
325 | Command alist.
326 |
327 | #### `quickrun-option-command`
328 |
329 | Command key(Expanded to %c)
330 |
331 | #### `quickrun-option-cmdkey`
332 |
333 | Command key of command parameter.
334 |
335 | #### `quickrun-option-cmdopt`
336 |
337 | Command option(Expanded to %o)
338 |
339 | #### `quickrun-option-args`
340 |
341 | Program argument(Expanded to %a.)
342 |
343 | #### `quickrun-option-shebang`
344 |
345 | If this value is `non-nil` and first line of source file is started "#!",
346 | the following string is treated as ":command".
347 |
348 | #### `quickrun-option-outputter`
349 |
350 | Outputter function. See *Outputter* section
351 |
352 | ### Example of buffer local variable
353 |
354 | Setting C++11.
355 |
356 | ```c++
357 | #include
358 | #include
359 | #include
360 |
361 | int main (int argc, char *argv[])
362 | {
363 | std::vector lst = { "a", "b", "c", "d" };
364 |
365 | for (auto x : lst) {
366 | std::cout << "[" << x << "]" << std::endl;
367 | }
368 |
369 | for (auto i = 1; i < argc; i++) {
370 | std::cout << "[" << argv[i] << "]" << std::endl;
371 | }
372 |
373 | return 0;
374 | }
375 |
376 | /*
377 | Local Variables:
378 | quickrun-option-cmd-alist: ((:command . "g++")
379 | (:exec . ("%c -std=c++0x -o %n %s"
380 | "%n apple orange melon"))
381 | (:remove . ("%n")))
382 | End:
383 | */
384 | ```
385 |
386 | ## Hooks
387 |
388 | #### `quickrun-after-run-hook`
389 |
390 | Run hooks after execute all commands.
391 |
392 | ## Outputter
393 |
394 | Outputter is a function for processing command output. Default outputter is
395 | to output to \*quickrun\* buffer and processing ANSI Color sequence.
396 |
397 | `quickrun.el` defines following functions as default.
398 |
399 | #### `buffer:buffername`
400 |
401 | Output to buffer. [outputter *buffer* sample](sample/sample_outputter_buffer.pl)
402 |
403 | #### `file:filename`
404 |
405 | Output to file. [outputter *file* sample](sample/sample_outputter_file.pl)
406 |
407 | #### `variable:varname`
408 |
409 | Output to variable. [outputter *variable* sample](sample/sample_outputter_variable.pl)
410 |
411 | #### `browser`
412 |
413 | Output to Web browser(using function *browse-url*) [outputter *browser* sample](sample/sample_outputter_browser.pl)
414 |
415 | #### `message`
416 |
417 | Output to \*Message\* buffer(using function *message*) [outputter *message* sample](sample/sample_outputter_message.pl)
418 |
419 | #### `multi`
420 |
421 | Use multiple outputters. [outputter *multi* sample](sample/sample_outputter_multi.pl)
422 |
423 | #### `null`
424 |
425 | No output. [outputter *null* sample](sample/sample_outputter_null.pl)
426 |
427 | ## Using quickrun as function from other functions
428 |
429 | `quickrun` can be used as function from other functions.
430 | You can pass configuration by `:source` argument.
431 | Sample is following:
432 |
433 | ```lisp
434 | (defun test-perl ()
435 | (interactive)
436 | (let* ((cmd "git rev-parse --show-toplevel")
437 | (topdir (with-temp-buffer
438 | (call-process-shell-command cmd nil t nil)
439 | (goto-char (point-min))
440 | (if (re-search-forward "^\\(.+\\)$" nil t)
441 | (match-string 1)))))
442 | (quickrun :source `((:command . "prove")
443 | (:default-directory . ,topdir)
444 | (:exec . ("%c -bv --color %s"))))))
445 | ```
446 |
447 | [melpa-link]: https://melpa.org/#/quickrun
448 | [melpa-stable-link]: https://stable.melpa.org/#/quickrun
449 | [melpa-badge]: https://melpa.org/packages/quickrun-badge.svg
450 | [melpa-stable-badge]: https://stable.melpa.org/packages/quickrun-badge.svg
451 | [jcs-elpa-link]: https://jcs-emacs.github.io/jcs-elpa/#/jcs-modeline
452 | [jcs-elpa-badge]: https://raw.githubusercontent.com/jcs-emacs/badges/master/elpa/v/jcs-modeline.svg
453 |
--------------------------------------------------------------------------------
/example/quickrun_conf.el:
--------------------------------------------------------------------------------
1 | ;;;
2 | ;;; Sample configuration of `quickrun.el'
3 | ;;;
4 |
5 | ;; require quickrun.el
6 | (require 'quickrun)
7 |
8 | ;; You should assign key binding, if you often use `quickrun' commands.
9 | (global-set-key (kbd "") 'quickrun)
10 | (global-set-key (kbd "M-") 'quickrun-compile-only)
11 |
12 | ;; I recommend you set popwin for quickrun.el
13 | ;; See also http://www.emacswiki.org/emacs/PopWin
14 | (push '("*quickrun*") popwin:special-display-config)
15 |
16 | ;; Add C++ command for C11 and set it default in C++ file.
17 | (quickrun-add-command "c++/c11"
18 | '((:command . "g++")
19 | (:exec . ("%c -std=c++11 %o -o %e %s"
20 | "%e %a"))
21 | (:remove . ("%e")))
22 | :default "c++")
23 |
24 | ;; Override existed command
25 | (quickrun-add-command "c/gcc"
26 | '((:exec . ("%c -std=c++11 %e -o %e %s"
27 | "%e %a")))
28 | :override t)
29 |
30 | ;; Add pod command and set to use when extension of file is '.pod'
31 | ;; or major-mode of file is pod-mode.
32 | (quickrun-add-command "pod"
33 | '((:command . "perldoc")
34 | (:exec . "%c -T -F %s"))
35 | :mode 'pod-mode)
36 |
37 | ;; File suffix is '.pod', then `quickrun' use "pod" command-key.
38 | (add-to-list 'quickrun-file-alist '("\\.pod$" . "pod"))
39 |
40 | ;; If you have gcc and clang, quickrun set `gcc' as default,
41 | ;; `quickrun-set-default' change default command(2nd argument)
42 | ;; in language(1st argument).
43 | ;; Following, quickrun uses clang in C file.
44 | (quickrun-set-default "c" "c/clang")
45 |
--------------------------------------------------------------------------------
/quickrun.el:
--------------------------------------------------------------------------------
1 | ;;; quickrun.el --- Run commands quickly -*- lexical-binding: t; -*-
2 |
3 | ;; Copyright (C) 2017 by Syohei YOSHIDA
4 | ;; Copyright (C) 2020-2025 by Jen-Chieh Shen
5 |
6 | ;; Author: Syohei YOSHIDA
7 | ;; Maintainer: Jen-Chieh Shen
8 | ;; URL: https://github.com/emacsorphanage/quickrun
9 | ;; Version: 2.3.1
10 | ;; Package-Requires: ((emacs "26.1") (ht "2.0"))
11 | ;; Keywords: tools
12 |
13 | ;; This program is free software; you can redistribute it and/or modify
14 | ;; it under the terms of the GNU General Public License as published by
15 | ;; the Free Software Foundation, either version 3 of the License, or
16 | ;; (at your option) any later version.
17 |
18 | ;; This program is distributed in the hope that it will be useful,
19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | ;; GNU General Public License for more details.
22 |
23 | ;; You should have received a copy of the GNU General Public License
24 | ;; along with this program. If not, see .
25 |
26 | ;;; Commentary:
27 |
28 | ;; quickrun.el executes editing buffer. quickrun.el selects commands to execute
29 | ;; buffer automatically. Please see https://github.com/emacsorphanage/quickrun
30 | ;; for more information.
31 | ;;
32 | ;; This package respects `quickrun.vim' developed by thinca
33 | ;; - https://github.com/thinca/vim-quickrun
34 | ;;
35 | ;; To use this package, add these lines to your .emacs file:
36 | ;; (require 'quickrun)
37 | ;;
38 | ;; And you call 'M-x quickrun'.
39 | ;;
40 |
41 | ;;; Code:
42 |
43 | (require 'cl-lib)
44 | (require 'ansi-color)
45 | (require 'em-banner)
46 | (require 'eshell)
47 |
48 | (require 'ht)
49 |
50 | ;; for warnings of byte-compile
51 | (declare-function anything "anything")
52 | (declare-function helm "helm")
53 | (declare-function tramp-dissect-file-name "tramp")
54 | (declare-function tramp-file-name-localname "tramp")
55 | (declare-function clear-image-cache "image")
56 |
57 | (defgroup quickrun nil
58 | "Execute buffer quickly."
59 | :group 'processes
60 | :prefix 'quickrun)
61 |
62 | (defcustom quickrun-timeout-seconds 10
63 | "Timeout seconds for running too long process."
64 | :type 'integer
65 | :group 'quickrun)
66 |
67 | (defcustom quickrun-focus-p t
68 | "If this value is `nil`, quickrun.el does not move focus to output buffer."
69 | :type 'boolean
70 | :group 'quickrun)
71 |
72 | (defcustom quickrun-truncate-lines t
73 | "The `truncate-lines' value for `*quickrun*` buffer."
74 | :type 'boolean
75 | :group 'quickrun)
76 |
77 | (defcustom quickrun-input-file-extension ".qrinput"
78 | "Extension of input file name."
79 | :type '(choice (string :tag "Extension of quickrun input file")
80 | (boolean :tag "Not use input file" nil))
81 | :group 'quickrun)
82 |
83 | (defcustom quickrun-debug nil
84 | "Enable debug message."
85 | :type 'boolean
86 | :group 'quickrun)
87 |
88 | (defcustom quickrun-output-only nil
89 | "If non-nil, omit the header and footer from the output."
90 | :type 'boolean
91 | :group 'quickrun)
92 |
93 | (defconst quickrun--buffer-name "*quickrun*")
94 | (defvar quickrun--executed-file nil)
95 | (defvar quickrun--remove-files nil)
96 | (defvar quickrun--compile-only-flag nil)
97 | (defvar quickrun--original-buffer nil)
98 | (defvar quickrun--original-outputter nil)
99 |
100 | (defun quickrun-2str (obj)
101 | "Convert OBJ to string."
102 | (format "%s" obj))
103 |
104 | (defmacro quickrun--awhen (test &rest body)
105 | "Anaphoric when. If TEST is non-nil, do BODY (include `it')."
106 | (declare (indent 1))
107 | `(let ((it ,test)) (when it ,@body)))
108 |
109 | (defun quickrun--mklist (obj)
110 | "Ensure OBJ is a list."
111 | (if (listp obj) obj (list obj)))
112 |
113 | (defsubst quickrun--log (fmt &rest args)
114 | "Log if `quickrun-debug' is non-nil.
115 | FMT and ARGS passed `message'."
116 | (when quickrun-debug
117 | (apply 'message fmt args)))
118 |
119 | (defsubst quickrun--windows-p ()
120 | "Return non-nil if windows."
121 | (memq system-type '(ms-dos windows-nt cygwin)))
122 |
123 | ;;
124 | ;; file local variable
125 | ;; Based on shadow.el. https://raw.github.com/mooz/shadow.el/master/shadow.el
126 | ;;
127 | (defmacro quickrun--defvar (name &optional value safep doc)
128 | "Define buffer-local and safe-local variable."
129 | (declare (indent defun))
130 | `(progn
131 | (defvar ,name ,value ,doc)
132 | (make-variable-buffer-local (quote ,name))
133 | ;; Suppress file local variable warning
134 | ,(when safep
135 | `(put (quote ,name) 'safe-local-variable (quote ,safep)))))
136 |
137 | (quickrun--defvar quickrun-option-cmd-alist
138 | nil listp
139 | "Specify command alist directly as file local variable")
140 |
141 | (quickrun--defvar quickrun-option-command
142 | nil stringp
143 | "Specify command directly as file local variable")
144 |
145 | (quickrun--defvar quickrun-option-cmdkey
146 | nil stringp
147 | "Specify language key directly as file local variable")
148 |
149 | (quickrun--defvar quickrun-option-cmdopt
150 | nil stringp
151 | "Specify command option directly as file local variable")
152 |
153 | (quickrun--defvar quickrun-option-args
154 | nil stringp
155 | "Specify command argument directly as file local variable")
156 |
157 | (defun quickrun--outputter-p (_x)
158 | "Not documented."
159 | (lambda (x)
160 | (or (functionp x) (symbolp x) (stringp x)
161 | (quickrun--outputter-multi-p x))))
162 |
163 | (quickrun--defvar quickrun-option-outputter
164 | nil quickrun--outputter-p
165 | "Specify format function output buffer as file local variable")
166 |
167 | (quickrun--defvar quickrun-option-shebang
168 | t booleanp
169 | "Select using command from schebang as file local variable")
170 |
171 | (quickrun--defvar quickrun-option-timeout-seconds
172 | nil integerp
173 | "Timeout seconds as file local variable")
174 |
175 | (quickrun--defvar quickrun-option-default-directory
176 | nil file-directory-p
177 | "Default directory where command is executed")
178 |
179 | ;; hooks
180 | (defvar quickrun-after-run-hook nil
181 | "Run hook after execute quickrun.")
182 |
183 | (defvar quickrun--temporary-file nil)
184 |
185 | ;; Language specific functions
186 |
187 | (defun quickrun--gnuplot-execute ()
188 | "Not documented."
189 | (setq quickrun--temporary-file (concat (make-temp-name "quickrun-gnuplot") ".png"))
190 | (let ((terminal-option "set terminal png")
191 | (output-option (format "set output \"%s\"" quickrun--temporary-file)))
192 | (push quickrun--temporary-file quickrun--remove-files)
193 | (concat "%c -e '" terminal-option "' -e '" output-option "' %s")))
194 |
195 | (defun quickrun--gnuplot-outputter ()
196 | "Not documented."
197 | (clear-image-cache)
198 | (insert-file-contents quickrun--temporary-file)
199 | (image-mode))
200 |
201 | ;;
202 | ;;; language command parameters
203 |
204 | (defvar quickrun--language-alist
205 | '(("asm/masm" . ((:command . "ml")
206 | (:exec . ("%c /c /coff %s"
207 | "link /subsystem:windows %n.obj"
208 | "%n.exe"))
209 | (:compile-only . "%c /c /coff %s")
210 | (:remove . ("%n.obj" "%n.exe"))
211 | (:description . "Compile Assembly file with masm and execute")))
212 | ("asm/masm64" . ((:command . "ml64")
213 | (:exec . ("%c /c /coff %s"
214 | "link /subsystem:windows %n.obj"
215 | "%n.exe"))
216 | (:compile-only . "%c /c /coff %s")
217 | (:remove . ("%n.obj" "%n.exe"))
218 | (:description . "Compile Assembly file with masm x64 and execute")))
219 | ("asm/nasm" . ((:command . "nasm")
220 | (:exec . ("%c -f elf64 %o %s -o %e.o" "ld -o %e %e.o" "%e %a"))
221 | (:remove . ("%e" "%e.o"))
222 | (:description . "Compile Assembly file with nasm and execute")))
223 | ("applescript" . ((:command . "osascript")
224 | (:description . "Run apple script")))
225 |
226 | ("c/gcc" . ((:command . "gcc")
227 | (:exec . ("%c -x c %o -o %e %s" "%e %a"))
228 | (:compile-only . "%c -Wall -Werror %o -o %e %s")
229 | (:remove . ("%e"))
230 | (:description . "Compile C file with gcc and execute")))
231 | ("c/clang" . ((:command . "clang")
232 | (:exec . ("%c -x c %o -o %e %s" "%e %a"))
233 | (:compile-only . "%c -Wall -Werror %o -o %e %s")
234 | (:remove . ("%e"))
235 | (:description . "Compile C file with llvm/clang and execute")))
236 |
237 | ("c/cl" . ((:command . "cl")
238 | (:exec . ("%c /Tc %o %s /nologo /Fo%n.obj /Fe%n.exe"
239 | "%n %a"))
240 | (:compile-only . "%c %o %s /Wall /nologo /Fo%n.obj /Fe%n.exe")
241 | (:remove . ("%n.obj" "%n.exe"))
242 | (:description . "Compile C file with VC++/cl and execute")))
243 |
244 | ("c++/g++" . ((:command . "g++")
245 | (:exec . ("%c -x c++ %o -o %e %s" "%e %a"))
246 | (:compile-only . "%c -Wall -Werror %o -o %e %s")
247 | (:remove . ("%e"))
248 | (:description . "Compile C++ file with g++ and execute")))
249 |
250 | ("c++/clang++" . ((:command . "clang++")
251 | (:exec . ("%c -x c++ %o -o %e %s" "%e %a"))
252 | (:compile-only . "%c -Wall -Werror %o -o %e %s")
253 | (:remove . ("%e"))
254 | (:description . "Compile C++ file with llvm/clang++ and execute")))
255 |
256 | ("c++/cl" . ((:command . "cl")
257 | (:exec . ("%c /Tp %o %s /nologo /Fo%n.obj /Fe%n.exe"
258 | "%n %a"))
259 | (:compile-only . "%c %o %s /Wall /nologo /Fo%n.obj /Fe%n.exe")
260 | (:remove . ("%n.obj" "%n.exe"))
261 | (:description . "Compile C++ file with VC/cl and execute")))
262 |
263 | ("objc" . ((:command . "gcc")
264 | (:exec . ((lambda ()
265 | (if (eq system-type 'darwin)
266 | "%c -x objective-c %o -o %e %s -framework foundation"
267 | "%c -x objective-c %o -o %e %s -lobjc"))
268 | "%e %a"))
269 | (:remove . ("%e"))
270 | (:description . "Compile Objective-C file with gcc and execute")))
271 |
272 | ("c#/dotnet" . ((:command . "dotnet run")
273 | (:remove . ("bin" "obj"))
274 | (:compile-only . "dotnet build")
275 | (:description . "Run .NET project")))
276 |
277 | ("c#/mono" . ((:command . "mono")
278 | (:exec . ("mcs %o %s" "%c %n.exe %a"))
279 | (:remove . ("%n.exe"))
280 | (:description . "Compile C# and execute with mono(mcs)")))
281 |
282 | ("d" . ((:command . "dmd")
283 | (:exec . ("%c %o -of%e %s" "%e %a"))
284 | (:remove . ("%e" "%n.o"))
285 | (:description . "Compile D language file and execute")))
286 |
287 | ("fortran/gfortran" . ((:command . "gfortran")
288 | (:exec . ("%c %o -o %e %s" "%e %a"))
289 | (:remove . ("%e"))
290 | (:description . "Compile Fortran language with gfortran")))
291 |
292 | ("java" . ((:command . "java")
293 | (:compile-only . "javac -Werror %o %s")
294 | (:exec . ("javac %o %s" "%c %N %a"))
295 | (:remove . ("%n.class"))
296 | (:tempfile . nil)
297 | (:description . "Compile Java file and execute")))
298 |
299 | ("perl" . ((:command . "perl") (:compile-only . "%c -wc %s")
300 | (:description . "Run Perl script")))
301 | ("perl6" . ((:command . "perl6") (:compile-only . "%c -c %s")
302 | (:description . "Run Perl6 script")))
303 | ("ruby/ruby" . ((:command . "ruby") (:compile-only . "%c -wc %s")
304 | (:description . "Run Ruby script")))
305 | ("ruby/mruby" . ((:command . "mruby")
306 | (:exec . ("mrbc %s" "mruby -b %N.mrb"))
307 | (:compile-only . "mrbc -c %s")
308 | (:remove . ("%n.mrb"))
309 | (:description . "Run mruby script")))
310 | ("python" . ((:command . "python") (:compile-only . "pyflakes %s")
311 | (:description . "Run Python script")))
312 | ("php" . ((:command . "php") (:compile-only . "%c -l %s")
313 | (:description . "Run PHP script")))
314 |
315 | ("elisp/emacs" . ((:command . "emacs")
316 | (:exec . "%c -q --no-site-file --batch -l %s")
317 | (:description . "Run Elisp as script file")))
318 | ("elisp/eask" . ((:command . "eask load")
319 | (:exec . "%c %s")
320 | (:description . "Run Elisp as script file through Eask (local scope)")))
321 | ("elisp/eask-g" . ((:command . "eask load")
322 | (:exec . "%c %s -g")
323 | (:description . "Run Elisp as script file through Eask (global scope)")))
324 | ("elisp/eask-c" . ((:command . "eask load")
325 | (:exec . "%c %s -c")
326 | (:description . "Run Elisp as script file through Eask (configuration scope)")))
327 |
328 | ("lisp/clisp" . ((:command . "clisp")
329 | (:description . "Run Lisp file with clisp")))
330 | ("lisp/sbcl" . ((:command . "sbcl")
331 | (:exec . "%c --script %s %a")
332 | (:description . "Run Lisp file with sbcl")))
333 | ("lisp/ccl" . ((:command . "ccl")
334 | (:exec . "%c --load %s --eval '(quit)'")
335 | (:description . "Run Lisp file with ccl")))
336 | ("scheme/gosh" . ((:command . "gosh")
337 | (:description . "Run Scheme file with gosh(Gauche)")))
338 | ("st/gst" . ((:command . "gst")
339 | (:exec . "%c -f %s %a")
340 | (:description . "Run Smalltalk file with GNU Smalltalk")))
341 | ("racket" . ((:command . "racket")
342 | (:exec . "%c --require-script %s")
343 | (:description . "Run racket script")))
344 |
345 | ("clojure/jark" . ((:command . "jark")
346 | (:description . "Run Clojure file with jark")))
347 | ("clojure/clj-env-dir" . ((:command . "clj-env-dir")
348 | (:description . "Run Clojure file with clj-env-dir")))
349 |
350 | ("javascript/node" . ((:command . "node")
351 | (:description . "Run JavaScript file with Node.js")))
352 | ("javascript/v8" . ((:command . "v8")
353 | (:description . "Run JavaScript file with v8")))
354 | ("javascript/js" . ((:command . "js")
355 | (:description . "Run JavaScript file with js(Rhino)")))
356 | ("javascript/jrunscript" . ((:command . "jrunscript")
357 | (:description . "Run JavaScript file with jrunscript")))
358 | ("javascript/phantomjs" . ((:command . "phantomjs")
359 | (:description . "Run JavaScript file with phantomjs")))
360 | ("javascript/cscript" . ((:command . "cscript")
361 | (:exec . "%c //e:jscript %o %s %a")
362 | (:cmdopt . "//Nologo")
363 | (:description . "Run JavaScript file with cscript")))
364 | ("javascript/deno" . ((:command . "deno")
365 | (:exec . "%c run -A %s")
366 | (:compile-only . "%c compile %s")
367 | (:description . "Run JavaScript file with deno")))
368 |
369 | ("coffee" . ((:command . "coffee")
370 | (:compile-only . "coffee --print %s")
371 | (:compile-conf . ((:compilation-mode . nil) (:mode . js-mode)))
372 | (:description . "Run Coffee script")))
373 |
374 | ("jsx" . ((:command . "jsx")
375 | (:exec . "%c --run %o %s %a")
376 | (:compile-only . "%c %o %s %s")
377 | (:compile-conf . ((:compilation-mode . nil) (:mode . js-mode)))
378 | (:description . "Run JSX script")))
379 |
380 | ("typescript/tsc" . ((:command . "tsc")
381 | (:exec . ("%c --target es5 --module commonjs %o %s %a" "node %n.js"))
382 | (:compile-only . "%c %o %s %s")
383 | (:compile-conf . ((:compilation-mode . nil) (:mode . js-mode)))
384 | (:remove . ("%n.js"))
385 | (:description . "Run TypeScript script")))
386 | ("typescript/deno" . ((:command . "deno")
387 | (:exec . "%c run -A %s")
388 | (:compile-only . "%c compile %s")
389 | (:compile-conf . ((:compilation-mode . nil) (:mode . js-mode)))
390 | (:remove . ("%n.js"))
391 | (:description . "Run TypeScript script with deno")))
392 |
393 | ("markdown/Markdown.pl" . ((:command . "Markdown.pl")
394 | (:description . "Convert Markdown to HTML with Markdown.pl")))
395 | ("markdown/bluecloth" . ((:command . "bluecloth")
396 | (:cmdopt . "-f")
397 | (:description . "Convert Markdown to HTML with bluecloth")))
398 | ("markdown/kramdown" . ((:command . "kramdown")
399 | (:description . "Convert Markdown to HTML with kramdown")))
400 | ("markdown/pandoc" . ((:command . "pandoc")
401 | (:exec . "%c --from=markdown --to=html %o %s %a")
402 | (:description . "Convert Markdown to HTML with pandoc")))
403 | ("markdown/redcarpet" . ((:command . "redcarpet")
404 | (:description . "Convert Markdown to HTML with redcarpet")))
405 |
406 | ("haskell" . ((:command . "runghc")
407 | (:description . "Run Haskell file with runghc(GHC)")))
408 |
409 | ("go/go" . ((:command . "go")
410 | (:exec . ((lambda ()
411 | (if (string-match-p "_test\\.go\\'" (or (buffer-file-name)
412 | (buffer-name)))
413 | "%c test %o"
414 | "%c run %o %s %a"))))
415 | (:compile-only . "%c build -o /dev/null %s %o %a")
416 | (:tempfile . nil)
417 | (:description . "Compile go file and execute with 'go'")))
418 | ("go/gccgo" . ((:command . "gccgo")
419 | (:exec . ("%c -static-libgcc %o -o %e %s"
420 | "%e %a"))
421 | (:remove . ("%e"))
422 | (:description . "Compile Go file with 'gccgo'")))
423 |
424 | ("io" . ((:command . "io")
425 | (:description . "Run IO Language script")))
426 | ("lua" . ((:command . "lua")
427 | (:description . "Run Lua script")))
428 | ("groovy" . ((:command . "groovy")
429 | (:description . "Run Groovy")))
430 | ("scala" . ((:command . "scala")
431 | (:cmdopt . "-Dfile.encoding=UTF-8")
432 | (:description . "Run Scala file with scala command")))
433 |
434 | ("haml" . ((:command . "haml")
435 | (:exec . "%c %o %s")
436 | (:description . "Convert HAML to HTML")))
437 | ("sass" . ((:command . "sass")
438 | (:exec . "%c %o --no-cache %s")
439 | (:description . "Convert SASS to CSS")))
440 | ("less" . ((:command . "lessc")
441 | (:description . "Convert LESS to CSS")))
442 |
443 | ("erlang" . ((:command . "escript")
444 | (:description . "Run Erlang file with escript")))
445 | ("ocaml" . ((:command . "ocamlc")
446 | (:exec . ("%c %o -o %e %s"
447 | "%e %a"))
448 | (:remove . ("%e" "%n.cmi" "%n.cmo"))
449 | (:description . "Compile Ocaml file with ocamlc and execute")))
450 |
451 | ("fsharp" . ((:command . "fsharpc")
452 | (:exec . ("%c %o --nologo -o %n.exe %s" "%n.exe %a"))
453 | (:remove . ("%n.exe"))
454 | (:description . "Compile F# file with fsharpc and execute")))
455 |
456 | ("shellscript" . ((:command . (lambda () sh-shell))
457 | (:description . "Run Shellscript file")))
458 | ("awk" . ((:command . "awk")
459 | (:exec . "%c %o -f %s %a")
460 | (:description . "Run AWK script")))
461 |
462 | ("rust" . ((:command . "rustc")
463 | (:exec . ("%c %o -o %e %s" "%e %a"))
464 | (:compile-only . "%c %o -o %e %s")
465 | (:remove . ("%e"))
466 | (:description . "Compile rust and execute")))
467 |
468 | ("dart/checked" . ((:command . "dart")
469 | (:cmdopt . "--enable-asserts")
470 | (:description . "Run Dart with '--enable-asserts' option")))
471 | ("dart/production" . ((:command . "dart")
472 | (:description . "Run Dart WITHOUT '--enable-asserts' option")))
473 |
474 | ("elixir" . ((:command . "elixir")
475 | (:description . "Run Elixir script")))
476 |
477 | ("tcl" . ((:command . "tclsh")
478 | (:description . "Run Tcl script")))
479 |
480 | ("swift/swift" . ((:command . "swift")
481 | (:exec . ("%c %o %s %a"))
482 | (:description . "Compile swift and execute")))
483 |
484 | ("swift/xcrun" . ((:command . "xcrun")
485 | (:exec . ("%c swift %o %s %a"))
486 | (:description . "Compile swift and execute with xcrun")))
487 |
488 | ("ats" . ((:command . "patscc")
489 | (:exec . ("%c -DATS_MEMALLOC_LIBC %o -o %e %s" "%e %a"))
490 | (:compile-only . "patsopt -o %n_dats.c --dynamic %s")
491 | (:remove . ("%e" "%n_dats.c"))
492 | (:description . "Compile ATS2 and execute")))
493 | ("r" . ((:command . "Rscript")
494 | (:exec "Rscript --vanilla %s")
495 | (:description . "Run an R script")))
496 |
497 | ("nim" . ((:command . "nim")
498 | (:exec . "%c compile --run --verbosity:0 %s")
499 | (:remove . ("nimcache" "%n"))
500 | (:tempfile . nil)
501 | (:description . "Run nim script")))
502 |
503 | ("nimscript" . ((:command . "nim")
504 | (:exec . "%c e --verbosity:0 %s")
505 | (:tempfile . nil)
506 | ;; Note that .nimle file also allows ‘.ini’ format, so
507 | ;; we can’t check by file extension.
508 | (:description . "Run NimScript (.nims or .nimble) file")))
509 |
510 | ("fish" . ((:command . "fish")
511 | (:description . "Run fish script")))
512 |
513 | ("julia" . ((:command . "julia")
514 | (:description . "Run julia script")))
515 | ("gnuplot" . ((:command . "gnuplot")
516 | (:exec . (quickrun--gnuplot-execute))
517 | (:outputter . quickrun--gnuplot-outputter)))
518 | ("kotlin" . ((:command . "kotlin")
519 | (:compile-only . "kotlinc -Werror %o %s")
520 | (:exec . ("kotlinc %o %s"
521 | (lambda ()
522 | (let ((file (file-name-nondirectory (file-name-sans-extension (buffer-file-name)))))
523 | (format "%%c %sKt %%a" (upcase-initials file))))))
524 | (:remove . ("%nKt.class"))
525 | (:tempfile . nil)
526 | (:description . "Compile Kotlin file and execute")))
527 | ("crystal" . ((:command . "crystal")
528 | (:compile-only . "%c build %s")
529 | (:description . "Run Crystal program")))
530 | ("v" . ((:command . "v")
531 | (:exec . "%c run %o %s %a")
532 | (:tempfile . nil)
533 | (:remove "%n")
534 | (:description . "Compile and run V programs")))
535 |
536 | ("zig" . ((:command . "zig")
537 | (:exec . "%c run %s")
538 | (:description . "Run zig file with Zig program")))
539 | ("zig/build" . ((:command . "zig")
540 | (:exec . "%c build run")
541 | (:description . "Run zig file with built-in package manager")))
542 | ("nix" . ((:command . "nix")
543 | (:exec . "%c eval --file %s")
544 | (:description . "Evaluate the Nix expression file"))))
545 | "List of each programming languages information.
546 | Parameter form is (\"language\" . parameter-alist). parameter-alist has
547 | 5 keys and those values , :command, :exec, :remove.
548 | :command pair is mandatory, other pairs are optional. Associated value
549 | should be string or a function which returns a string object.
550 |
551 | Assosiated values are
552 | :command = Program name which is used compiled or executed source code.
553 | :exec = Exec command template. If you omit this parameter, quickrun
554 | use default parameter \"%c %o %s %a\".
555 | :remove = Remove files or directories templates.
556 | Compiler or executor generates temporary files,
557 | you should specified this parameter.
558 | If value is List, quickrun removes each element.
559 | Every pair should be dot-pair.
560 |
561 | See explanation of quickrun--template-place-holders
562 | if you set your own language configuration.")
563 |
564 | (defvar quickrun-file-alist
565 | '(("\\.\\(scpt\\|applescript\\)\\'" . "applescript")
566 | ("\\.c\\'" . "c")
567 | ("\\.\\(cpp\\|cxx\\|C\\|cc\\)\\'" . "c++")
568 | ("\\.m\\'" . "objc")
569 | ("\\.cs\\'" . "c#")
570 | ("\\.\\(pl\\|pm\\)\\'" . "perl")
571 | ("\\.p[ml]?6\\'" . "perl6")
572 | ("\\.rb\\'" . "ruby")
573 | ("\\.py\\'" . "python")
574 | ("\\.php\\'" . "php")
575 | ("\\.\\(el\\|elisp\\)\\'" . "elisp")
576 | ("\\.\\(lisp\\|lsp\\)\\'" . "lisp")
577 | ("\\.\\(scm\\|scheme\\)\\'" . "scheme")
578 | ("\\.st\\'" . "st/gst")
579 | ("\\.rkt\\'" . "racket")
580 | ("\\.js\\'" . "javascript")
581 | ("\\.clj\\'" . "clojure")
582 | ("\\.erl\\'" . "erlang")
583 | ("\\.ml\\'" . "ocaml")
584 | ("\\.\\(fsx?\\|fsscript\\)\\'" . "fsharp")
585 | ("\\.go\\'" . "go")
586 | ("\\.io\\'" . "io")
587 | ("\\.lua\\'" . "lua")
588 | ("\\.hs\\'" . "haskell")
589 | ("\\.java\\'" . "java")
590 | ("\\.d\\'" . "d")
591 | ("\\.\\(f\\|for\\|f90\\|f95\\)\\'" . "fortran")
592 | ("\\.\\(md\\|markdown\\|mdown\\|mkdn\\)\\'" . "markdown")
593 | ("\\.coffee\\'" . "coffee")
594 | ("\\.jsx\\'" . "jsx")
595 | ("\\.ts\\'" . "typescript")
596 | ("\\.scala\\'" . "scala")
597 | ("\\.groovy\\'". "groovy")
598 | ("\\.haml\\'" . "haml")
599 | ("\\.sass\\'" . "sass")
600 | ("\\.less\\'" . "less")
601 | ("\\.\\(sh\\|bash\\|zsh\\|csh\\|csh\\)\\'" . "shellscript")
602 | ("\\.awk\\'" . "awk")
603 | ("\\.rs\\'" . "rust")
604 | ("\\.dart\\'" . "dart/checked")
605 | ("\\.exs?\\'" . "elixir")
606 | ("\\.tcl\\'" . "tcl")
607 | ("\\.swift\\'" . "swift")
608 | ("\\.dats\\'" . "ats")
609 | ("\\.\\(r\\|R\\)\\'" . "r")
610 | ("\\.nim\\'". "nim")
611 | ("\\.fish\\'" . "fish")
612 | ("\\.jl\\'" . "julia")
613 | ("\\.\\(gpi\\|plt\\)\\'" . "gnuplot")
614 | ("\\.kt\\'" . "kotlin")
615 | ("\\.cr\\'" . "crystal")
616 | ("\\.v\\'" . "v")
617 | ("\\.zig\\'" . "zig"))
618 | "Alist of (file-regexp . key)")
619 |
620 | (defvar quickrun--major-mode-alist
621 | '((applescript-mode . "applescript")
622 | (c-mode . "c")
623 | (c++-mode . "c++")
624 | (objc-mode . "objc")
625 | (csharp-mode . "c#")
626 | ((perl-mode cperl-mode) . "perl")
627 | (perl6-mode . "perl6")
628 | (ruby-mode . "ruby")
629 | (python-mode . "python")
630 | ((php-mode php-ts-mode phps-mode) . "php")
631 | (emacs-lisp-mode . "elisp")
632 | (lisp-mode . "lisp")
633 | (scheme-mode . "scheme")
634 | (smalltalk-mode . "st/gst")
635 | (racket-mode . "racket")
636 | ((javascript-mode js-mode js2-mode js3-mode) . "javascript")
637 | (clojure-mode . "clojure")
638 | (erlang-mode . "erlang")
639 | ((ocaml-mode tuareg-mode) . "ocaml")
640 | (fsharp-mode . "fsharp")
641 | (go-mode . "go")
642 | (io-mode . "io")
643 | (lua-mode . "lua")
644 | (haskell-mode . "haskell")
645 | (java-mode . "java")
646 | (d-mode . "d")
647 | (fortran-mode . "fortran")
648 | (markdown-mode . "markdown")
649 | (coffee-mode . "coffee")
650 | (jsx-mode . "jsx")
651 | (typescript-mode . "typescript")
652 | (scala-mode . "scala")
653 | (groove-mode . "groovy")
654 | (haml-mode . "haml")
655 | (sass-mode . "sass")
656 | ((less-mode less-css-mode) . "less")
657 | (sh-mode . "shellscript")
658 | (awk-mode . "awk")
659 | (rust-mode . "rust")
660 | (rustic-mode . "rust")
661 | (dart-mode . "dart/checked")
662 | (elixir-mode . "elixir")
663 | (tcl-mode . "tcl")
664 | (swift-mode . "swift")
665 | ((asm-mode nasm-mode masm-mode) . "asm")
666 | (ats-mode . "ats")
667 | (ess-mode . "r")
668 | (nim-mode . "nim")
669 | (nimscript-mode . "nimscript")
670 | (fish-mode . "fish")
671 | (julia-mode . "julia")
672 | (gnuplot-mode . "gnuplot")
673 | (kotlin-mode . "kotlin")
674 | (crystal-mode . "crystal")
675 | (v-mode . "v")
676 | (zig-mode . "zig"))
677 | "Alist of major-mode and langkey")
678 |
679 | (defun quickrun--decide-file-type (filename)
680 | "Decide file type by FILENAME."
681 | ;; First search by file extension, Second search by major-mode
682 | (or (let (case-fold-search) (assoc-default filename quickrun-file-alist 'string-match))
683 | (let ((case-fold-search t)) (assoc-default filename quickrun-file-alist 'string-match))
684 | (quickrun--find-from-major-mode-alist)))
685 |
686 | (defun quickrun--find-from-major-mode-alist ()
687 | "Not documented."
688 | (cl-loop for (lang . lang-info) in quickrun--major-mode-alist
689 | for lang-lst = (quickrun--mklist lang)
690 | when (memq major-mode lang-lst)
691 | return lang-info))
692 |
693 | (defun quickrun--command-info (lang)
694 | "Not documented."
695 | (or quickrun-option-cmd-alist
696 | (assoc-default lang quickrun--language-alist)
697 | (throw 'quickrun
698 | (format "not found [%s] language information" lang))))
699 |
700 | ;;
701 | ;;; Compile Only
702 |
703 | (defun quickrun--check-using-compilation-mode (compile-conf)
704 | "Not documented."
705 | (if (not compile-conf)
706 | t
707 | (let ((compilation-mode (assoc :compilation-mode compile-conf)))
708 | (if (not compilation-mode)
709 | t
710 | (cdr compilation-mode)))))
711 |
712 | (defun quickrun--pop-to-buffer (buf cb)
713 | "Not documented."
714 | (let ((win (selected-window)))
715 | (pop-to-buffer buf
716 | `((display-buffer-in-direction)
717 | (dedicated . t)))
718 | (funcall cb)
719 | (unless quickrun-focus-p
720 | (select-window win))))
721 |
722 | (defun quickrun--compilation-start (cmd compile-conf)
723 | "Not documented."
724 | (let ((use-compile (quickrun--check-using-compilation-mode compile-conf)))
725 | (cond (use-compile
726 | (setq compilation-finish-functions 'quickrun--compilation-finish-func)
727 | (compilation-start cmd t (lambda (_x) quickrun--buffer-name)))
728 | (t
729 | (with-current-buffer (get-buffer-create quickrun--buffer-name)
730 | (read-only-mode -1)
731 | (erase-buffer)
732 | (process-file-shell-command cmd nil t)
733 | (goto-char (point-min))
734 | (quickrun--awhen (assoc-default :mode compile-conf)
735 | (funcall it)
736 | (quickrun--pop-to-buffer
737 | (current-buffer) (lambda () (read-only-mode 1)))
738 | (read-only-mode 1)))
739 | (quickrun--remove-temp-files)))))
740 |
741 | (defun quickrun--compilation-finish-func (_buffer _str)
742 | "Not documented."
743 | (quickrun--remove-temp-files))
744 |
745 | ;;
746 | ;;; Execute
747 |
748 | (defvar quickrun--timeout-timer nil)
749 | (defvar quickrun--run-in-shell nil)
750 |
751 | (defsubst quickrun--concat-commands (cmd-lst)
752 | "Not documented."
753 | (mapconcat 'identity cmd-lst " && "))
754 |
755 | (defsubst quickrun--stdin-file-name ()
756 | "Not documented."
757 | (concat quickrun--executed-file quickrun-input-file-extension))
758 |
759 | (defsubst quickrun--stdin-file-regexp ()
760 | "Not documented."
761 | (concat quickrun-input-file-extension "\\'"))
762 |
763 | (defsubst quickrun--use-stdin-file-p ()
764 | "Not documented."
765 | (string-match-p (quickrun--stdin-file-regexp)
766 | (or (buffer-file-name) (buffer-name))))
767 |
768 | (defun quickrun--send-file-as-stdin (process file)
769 | "Not documented."
770 | (let ((open-buf-func (cond ((file-exists-p file) 'find-file-noselect)
771 | ((get-buffer file) 'get-buffer))))
772 | (when open-buf-func
773 | (quickrun--log "Send '%s' to STDIN of %s" file (process-name process))
774 | (with-current-buffer (funcall open-buf-func file)
775 | (process-send-region process (point-min) (point-max))
776 | (process-send-eof process)))))
777 |
778 | (defun quickrun--default-filter (proc output)
779 | "Not documented."
780 | (with-current-buffer (process-buffer proc)
781 | (read-only-mode -1)
782 | (goto-char (point-max))
783 | (let ((start (point)))
784 | (insert output)
785 | (ansi-color-apply-on-region start (point)))))
786 |
787 | (defun quickrun--get-timestamp ()
788 | "Return timestamp for quickrun buffer."
789 | (substring (current-time-string) 0 19))
790 |
791 | (defun quickrun--insert-header (process)
792 | "Insert header to PROCESS buffer."
793 | (unless quickrun-output-only
794 | (with-current-buffer (process-buffer process)
795 | (let ((inhibit-read-only t)
796 | (time (quickrun--get-timestamp)))
797 | (insert "-*- mode: quickrun-; default-directory: \""
798 | default-directory
799 | "\" -*-\n")
800 | (insert "Quickrun started at " time "\n\n")))))
801 |
802 | (defun quickrun--insert-footer (process code)
803 | "Insert footer to PROCESS buffer with exit CODE."
804 | (unless quickrun-output-only
805 | (with-current-buffer (process-buffer process)
806 | (let ((inhibit-read-only t)
807 | (time (quickrun--get-timestamp)))
808 | (insert "\n\n")
809 | (if (zerop code)
810 | (insert "Quickrun finished at " time "\n")
811 | (insert "Quickrun exited abnormally with code "
812 | (quickrun-2str code)
813 | " at " time "\n"))))))
814 |
815 | (defun quickrun--exec (cmd-lst src mode)
816 | "Not documented."
817 | (if quickrun--run-in-shell
818 | (quickrun--send-to-shell cmd-lst)
819 | (ignore-errors
820 | (let* ((next-cmd (car cmd-lst))
821 | (rest-cmds (cdr cmd-lst))
822 | (process (quickrun--exec-cmd next-cmd))
823 | (outputter (or quickrun-option-outputter
824 | 'quickrun--default-outputter)))
825 | (when (and (null rest-cmds) quickrun-input-file-extension)
826 | (let ((file (quickrun--stdin-file-name)))
827 | (quickrun--send-file-as-stdin process file)))
828 | (when (eq outputter 'quickrun--default-outputter)
829 | (set-process-filter process #'quickrun--default-filter))
830 | (set-process-sentinel process
831 | (quickrun--make-sentinel rest-cmds outputter src mode))
832 | (quickrun--insert-header process)))))
833 |
834 | (defvar quickrun--eshell-buffer-name "*eshell-quickrun*")
835 | (defvar quickrun--shell-last-command)
836 |
837 | (defun quickrun--eshell-finish ()
838 | "Not documented."
839 | (quickrun--remove-temp-files)
840 | (remove-hook 'eshell-post-command-hook 'quickrun--eshell-post-hook))
841 |
842 | (defun quickrun--eshell-window-restore ()
843 | "Not documented."
844 | (interactive)
845 | (jump-to-register :quickrun-shell))
846 |
847 | (defvar quickrun--eshell-map
848 | (let ((map (make-sparse-keymap)))
849 | (set-keymap-parent map eshell-mode-map)
850 | (define-key map (kbd "q") 'quickrun--eshell-window-restore)
851 | map))
852 |
853 | (defun quickrun--eshell-post-hook ()
854 | "Not documented."
855 | (let ((rerun-p nil)
856 | (prompt "Press 'r' to run again, any other key to finish"))
857 | (unwind-protect
858 | (ignore-errors
859 | (let ((input (read-char prompt)))
860 | (when (char-equal input ?r)
861 | (quickrun--insert-command quickrun--shell-last-command)
862 | (setq rerun-p t))))
863 | (unless rerun-p
864 | (quickrun--eshell-finish)
865 | (read-only-mode 1)
866 | (use-local-map quickrun--eshell-map)))))
867 |
868 | (defun quickrun--insert-command (cmd-str)
869 | "Not documented."
870 | (goto-char (point-max))
871 | (eshell-kill-input)
872 | (insert cmd-str)
873 | (eshell-send-input))
874 |
875 | (defun quickrun--send-to-shell (cmd-lst)
876 | "Not documented."
877 | (window-configuration-to-register :quickrun-shell)
878 | (let ((buf (get-buffer quickrun--buffer-name))
879 | (win (selected-window)))
880 | (pop-to-buffer buf)
881 | (let ((cmd-str (quickrun--concat-commands cmd-lst))
882 | (eshell-buf (get-buffer quickrun--eshell-buffer-name))
883 | (eshell-buffer-name quickrun--eshell-buffer-name)
884 | (eshell-banner-message ""))
885 | (when eshell-buf
886 | (kill-buffer eshell-buf))
887 | (eshell)
888 | (quickrun--kill-quickrun-buffer)
889 | (setq-local quickrun--shell-last-command cmd-str)
890 | (add-hook 'eshell-post-command-hook 'quickrun--eshell-post-hook)
891 | (quickrun--insert-command cmd-str)
892 | (unless quickrun-focus-p
893 | (select-window win)))))
894 |
895 | (defsubst quickrun--default-directory ()
896 | "Not documented."
897 | (or quickrun-option-default-directory default-directory))
898 |
899 | (defun quickrun--set-default-directory (cmd-key)
900 | "Not documented."
901 | (let ((cmd-info (quickrun--command-info cmd-key)))
902 | (quickrun--awhen (assoc-default :default-directory cmd-info)
903 | (let ((formatted (file-name-as-directory it)))
904 | (unless (file-directory-p formatted)
905 | (throw 'quickrun (format "'%s' is not existed directory" it)))
906 | (let* ((has-space (string-match-p "[ \t]" formatted))
907 | (quoted-name (shell-quote-argument
908 | (if has-space
909 | (concat "\"" formatted "\"")
910 | formatted))))
911 | (setq quickrun-option-default-directory quoted-name))))))
912 |
913 | (defsubst quickrun--process-connection-type (cmd)
914 | "Not documented."
915 | ;; for suppressing 'carriage return'(^M)
916 | (not (string-match-p "\\`php" cmd)))
917 |
918 | (defun quickrun--exec-cmd (cmd)
919 | "Not documented."
920 | (let ((program (car (split-string cmd)))
921 | (buf (get-buffer quickrun--buffer-name)))
922 | (with-current-buffer buf
923 | (read-only-mode -1)
924 | (erase-buffer))
925 | (let ((proc-name (format "quickrun-process-%s" program))
926 | (process-connection-type (quickrun--process-connection-type program))
927 | (default-directory (quickrun--default-directory)))
928 | (quickrun--log "Quickrun Execute: %s at %s" cmd default-directory)
929 | (let ((process (start-file-process-shell-command proc-name buf cmd)))
930 | (when (>= quickrun-timeout-seconds 0)
931 | (setq quickrun--timeout-timer
932 | (run-at-time quickrun-timeout-seconds nil
933 | 'quickrun--kill-process process)))
934 | process))))
935 |
936 | (defun quickrun--kill-process (process)
937 | "Not documented."
938 | (when (eq (process-status process) 'run)
939 | (kill-process process))
940 | (let ((buf (get-buffer quickrun--buffer-name)))
941 | (with-current-buffer buf
942 | (insert (format "\nTime out %s(running over %d second)"
943 | (process-name process)
944 | quickrun-timeout-seconds)))
945 | (quickrun--remove-temp-files)
946 | (quickrun--pop-to-buffer buf (lambda () (read-only-mode 1)))))
947 |
948 | (defun quickrun--remove-temp-files ()
949 | "Remove temporary files."
950 | (quickrun--log "Quickrun remove %s" quickrun--remove-files)
951 | (dolist (file quickrun--remove-files)
952 | (cond
953 | ((file-directory-p file) (delete-directory file t))
954 | ((file-exists-p file) (delete-file file))))
955 | (setq quickrun--remove-files nil))
956 |
957 | (defun quickrun--kill-running-process ()
958 | "Kill running process."
959 | (interactive)
960 | (let ((proc (get-buffer-process (current-buffer))))
961 | (if (not proc)
962 | (message "No Process!!")
963 | (message "Kill process: %s" (process-name proc))
964 | (kill-process proc))))
965 |
966 | (defvar quickrun--mode-map
967 | (let ((map (make-sparse-keymap)))
968 | (define-key map (kbd "q") 'quit-window)
969 | (define-key map (kbd "C-c C-c") 'quickrun--kill-running-process)
970 | map))
971 |
972 | (define-derived-mode quickrun--mode nil "Quickrun"
973 | "Major mode for Quickrun execution process."
974 | (read-only-mode 1)
975 | (setq-local truncate-lines quickrun-truncate-lines)
976 | (use-local-map quickrun--mode-map))
977 |
978 | ;;
979 | ;;; Predefined outputter
980 |
981 | (defvar quickrun--defined-outputter-symbol
982 | '((message . quickrun--outputter-message)
983 | (browser . quickrun--outputter-browser)
984 | (null . quickrun--outputter-null)
985 | (replace . quickrun--outputter-replace-region)
986 | (eval-print . quickrun--outputter-eval-print))
987 | "Not documented.")
988 |
989 | (defvar quickrun--defined-outputter-symbol-with-arg
990 | '(("^file:" . quickrun--outputter-file)
991 | ("^buffer:" . quickrun--outputter-buffer)
992 | ("^variable:" . quickrun--outputter-variable))
993 | "Not documented.")
994 |
995 | (defun quickrun--recenter (arg)
996 | "Recenter window with ARG."
997 | (with-selected-window (get-buffer-window quickrun--buffer-name)
998 | (recenter arg)))
999 |
1000 | (defun quickrun--default-outputter ()
1001 | "Not documented."
1002 | (quickrun--recenter -1))
1003 |
1004 | (defun quickrun--outputter-multi-p (outputter)
1005 | "Not documented."
1006 | (and (not (functionp outputter)) (listp outputter)
1007 | (eq (car outputter) 'multi)))
1008 |
1009 | (defun quickrun--defined-outputter-p (outputter)
1010 | "Not documented."
1011 | (cond ((quickrun--outputter-multi-p outputter) t)
1012 | ((or (symbolp outputter) (stringp outputter))
1013 | (let ((name (or (and (symbolp outputter) (symbol-name outputter))
1014 | outputter)))
1015 | (or (assoc outputter quickrun--defined-outputter-symbol)
1016 | (assoc-default name
1017 | quickrun--defined-outputter-symbol-with-arg
1018 | 'string-match))))))
1019 |
1020 | (defun quickrun--outputter-file (file)
1021 | "Not documented."
1022 | (write-region (point-min) (point-max) file))
1023 |
1024 | (defun quickrun--outputter-message ()
1025 | "Not documented."
1026 | (message "%s" (buffer-substring-no-properties (point-min) (point-max))))
1027 |
1028 | (defun quickrun--outputter-browser ()
1029 | "Not documented."
1030 | (browse-url-of-region (point-min) (point-max)))
1031 |
1032 | (defun quickrun--outputter-null ()
1033 | "Not documented."
1034 | (delete-region (point-min) (point-max))
1035 | (quickrun--kill-quickrun-buffer))
1036 |
1037 | (defun quickrun--outputter-replace-region ()
1038 | "Not documented."
1039 | (let ((output (buffer-substring-no-properties (point-min) (point-max))))
1040 | (with-current-buffer quickrun--original-buffer
1041 | (delete-region (region-beginning) (region-end))
1042 | (insert output)
1043 | (setq quickrun-option-outputter quickrun--original-outputter))))
1044 |
1045 | (defun quickrun--outputter-eval-print ()
1046 | "Not documented."
1047 | (let ((output (buffer-substring-no-properties (point-min) (point-max))))
1048 | (with-current-buffer quickrun--original-buffer
1049 | (forward-line 1)
1050 | (let ((start (point)))
1051 | (insert output)
1052 | (comment-region start (point))
1053 | (setq quickrun-option-outputter quickrun--original-outputter)))))
1054 |
1055 | (defun quickrun--outputter-buffer (bufname)
1056 | "Not documented."
1057 | (let ((str (buffer-substring (point-min) (point-max))))
1058 | (with-current-buffer (get-buffer-create bufname)
1059 | (erase-buffer)
1060 | (insert str))))
1061 |
1062 | (defun quickrun--outputter-variable (varname)
1063 | "Not documented."
1064 | (let ((symbol (intern varname)))
1065 | (set symbol (buffer-substring (point-min) (point-max)))))
1066 |
1067 | (defun quickrun--apply-outputter (op)
1068 | "Not documented."
1069 | (let ((buf (get-buffer quickrun--buffer-name))
1070 | (origbuf (current-buffer))
1071 | (outputters (or (and (quickrun--outputter-multi-p op) (cdr op))
1072 | (list op)))
1073 | (outputter-func nil))
1074 | (dolist (outputter outputters)
1075 | (setq outputter-func outputter)
1076 | (when (symbolp outputter)
1077 | (let* ((name (symbol-name outputter))
1078 | (func (assoc-default outputter
1079 | quickrun--defined-outputter-symbol))
1080 | (func-with-arg
1081 | (assoc-default name
1082 | quickrun--defined-outputter-symbol-with-arg
1083 | 'string-match)))
1084 | (cond (func (setq outputter-func func))
1085 | (func-with-arg
1086 | (when (string-match ":\\(.*\\)\\'" name)
1087 | (setq outputter-func
1088 | (lambda ()
1089 | (funcall func-with-arg
1090 | (match-string 1 name)))))))))
1091 | (with-current-buffer buf
1092 | (let ((quickrun--original-buffer origbuf))
1093 | (read-only-mode -1)
1094 | (funcall outputter-func)
1095 | (read-only-mode 1))))))
1096 |
1097 | (defun quickrun--apply-compilation-mode (input-file mode)
1098 | "Not documented."
1099 | (unless (string= input-file quickrun--executed-file)
1100 | (save-excursion
1101 | (goto-char (point-min))
1102 | (let ((case-fold-search nil))
1103 | (while (search-forward input-file nil t)
1104 | (replace-match quickrun--executed-file)))))
1105 | (compilation-mode mode))
1106 |
1107 | (defun quickrun--apply-colorizing (input-file mode)
1108 | "Not documented."
1109 | (with-current-buffer (get-buffer quickrun--buffer-name)
1110 | (read-only-mode -1)
1111 | (when (and quickrun--executed-file input-file)
1112 | (quickrun--apply-compilation-mode input-file mode)
1113 | (read-only-mode -1))
1114 | (quickrun--default-outputter)
1115 | (goto-char (point-min))
1116 | (read-only-mode 1)))
1117 |
1118 | (defun quickrun--make-sentinel (rest-commands outputter-func input orig-mode)
1119 | "Not documented."
1120 | (lambda (process _event)
1121 | ;; XXX Why reset `quickrun-option-outputter' ??
1122 | (setq quickrun-option-outputter outputter-func)
1123 | (when (memq (process-status process) '(exit signal))
1124 | (and quickrun--timeout-timer (cancel-timer quickrun--timeout-timer))
1125 | (let* ((exit-status (process-exit-status process))
1126 | (is-success (zerop exit-status)))
1127 | (quickrun--insert-footer process exit-status)
1128 | (delete-process process)
1129 | (cond ((and is-success rest-commands)
1130 | (quickrun--exec rest-commands input orig-mode))
1131 | (t
1132 | (if (not is-success)
1133 | (if (and (buffer-live-p quickrun--buffer-name)
1134 | (eq quickrun-option-outputter #'quickrun--default-outputter))
1135 | (quickrun--apply-colorizing input orig-mode)
1136 | (message "Failed: Exit Status=%d" exit-status))
1137 | (quickrun--apply-outputter outputter-func)
1138 | (run-hooks 'quickrun-after-run-hook))
1139 | (when (eq outputter-func 'quickrun--default-outputter)
1140 | (cond ((> scroll-conservatively 0) (quickrun--recenter nil))
1141 | ((/= scroll-step 0) (quickrun--recenter -1))))
1142 | (quickrun--remove-temp-files)))))))
1143 |
1144 | ;;
1145 | ;;; Composing command
1146 |
1147 | (defconst quickrun--template-place-holders
1148 | '("%c" "%o" "%s" "%S" "%a" "%d" "%n" "%N" "%e" "%E")
1149 | "A list of place holders of each language parameter.
1150 | Place holders are beginning with '%' and replaced by:
1151 | %c: :command parameter
1152 | %o: command options
1153 | %s: source code name
1154 | %S: source code name without extension
1155 | %a: program argument
1156 | %d: directory name
1157 | %n: absolute path of source code without extension
1158 | %N: source code path without extension
1159 | %e: absolute path of source code with executable extension(.exe, .out, .class)
1160 | %E: source code name with executable extension")
1161 |
1162 | (defun quickrun--executable-suffix (command)
1163 | "Not documented."
1164 | (cond ((string= command "java") ".class")
1165 | ((quickrun--windows-p) ".exe")
1166 | (t ".out")))
1167 |
1168 | (defun quickrun--real-file-name (src)
1169 | "Not documented."
1170 | (let ((buffile (buffer-file-name)))
1171 | (if (not (and buffile (file-remote-p buffile)))
1172 | src
1173 | (tramp-file-name-localname (tramp-dissect-file-name (buffer-file-name))))))
1174 |
1175 | (defun quickrun--place-holder-info (cmd cmdopt source args)
1176 | "Not documented."
1177 | (let* ((src (quickrun--real-file-name source))
1178 | (without-extension (file-name-sans-extension src))
1179 | (dirname (file-name-directory (expand-file-name src)))
1180 | (directory (substring dirname 0 (- (length dirname) 1)))
1181 | (executable-suffix (quickrun--executable-suffix cmd))
1182 | (executable-name (concat without-extension executable-suffix)))
1183 | `(("%c" . ,cmd)
1184 | ("%o" . ,cmdopt)
1185 | ("%s" . ,(file-name-nondirectory src))
1186 | ("%S" . ,(file-name-nondirectory without-extension))
1187 | ("%n" . ,(expand-file-name without-extension))
1188 | ("%N" . ,without-extension)
1189 | ("%d" . ,directory)
1190 | ("%e" . ,(expand-file-name executable-name))
1191 | ("%E" . ,executable-name)
1192 | ("%a" . ,args))))
1193 |
1194 | (defconst quickrun--default-tmpl-alist
1195 | '((:exec . "%c %o %s %a")))
1196 |
1197 | (defun quickrun--extract-template (key cmd-info &optional take-list)
1198 | "Not documented."
1199 | (let ((tmpl (or (assoc-default key cmd-info)
1200 | (assoc-default key quickrun--default-tmpl-alist))))
1201 | (when tmpl
1202 | (if take-list
1203 | (mapcar 'quickrun--eval-parameter (quickrun--mklist tmpl))
1204 | (quickrun--eval-parameter tmpl)))))
1205 |
1206 | (defun quickrun--eval-parameter (param)
1207 | "Not documented."
1208 | (cond ((functionp param)
1209 | (let* ((default-directory (quickrun--default-directory))
1210 | (ret (funcall param)))
1211 | (cond ((stringp ret) ret)
1212 | ((symbolp ret) (symbol-name ret))
1213 | (t
1214 | (throw 'quickrun
1215 | "template function should return symbol or string")))))
1216 | (t param)))
1217 |
1218 | (defun quickrun--get-shebang ()
1219 | "Not documented."
1220 | (save-excursion
1221 | (goto-char (point-min))
1222 | (when (looking-at "#![ \t]*\\(.*\\)$")
1223 | (match-string-no-properties 1))))
1224 |
1225 | (defun quickrun--template-argument (cmd-info src)
1226 | "Not documented."
1227 | (let ((cmd (or quickrun-option-command
1228 | (and quickrun-option-shebang (quickrun--get-shebang))
1229 | (quickrun--eval-parameter (assoc-default :command cmd-info))
1230 | (throw 'quickrun "Not found :command parameter")))
1231 | (cmd-opt (or quickrun-option-cmdopt
1232 | (quickrun--extract-template :cmdopt cmd-info) ""))
1233 | (arg (or quickrun-option-args
1234 | (quickrun--extract-template :args cmd-info) "")))
1235 | (quickrun--place-holder-info cmd cmd-opt src arg)))
1236 |
1237 | (defun quickrun--fill-templates (cmd-key src)
1238 | "Not documented."
1239 | (let* ((cmd-info (quickrun--command-info cmd-key))
1240 | (tmpl-arg (quickrun--template-argument cmd-info src))
1241 | (info (make-hash-table)))
1242 | ;; take one parameter
1243 | (cl-loop for key in '(:compile-only)
1244 | when (quickrun--extract-template key cmd-info)
1245 | do (puthash key (quickrun--fill-template it tmpl-arg) info))
1246 | ;; numerical value (non template)
1247 | (cl-loop for key in '(:timeout)
1248 | when (assoc-default key cmd-info)
1249 | do (puthash key it info))
1250 | ;; take one or more parameters
1251 | (cl-loop for key in '(:exec :remove)
1252 | when (quickrun--extract-template key cmd-info t)
1253 | do
1254 | (let ((filled-tmpls (mapcar (lambda (x)
1255 | (quickrun--fill-template x tmpl-arg))
1256 | it)))
1257 | (puthash key filled-tmpls info)))
1258 | ;; function parameter
1259 | (dolist (key '(:outputter))
1260 | (let ((func (assoc-default :outputter cmd-info)))
1261 | (when (and func (or (functionp func) (symbolp func)))
1262 | (puthash key func info))))
1263 | info))
1264 |
1265 | (defun quickrun--fill-template (tmpl info)
1266 | "Not documented."
1267 | (let ((place-holders quickrun--template-place-holders)
1268 | (str tmpl)
1269 | (case-fold-search nil))
1270 | (dolist (holder place-holders str)
1271 | (let ((rep (assoc-default holder info)))
1272 | (setq str (replace-regexp-in-string holder rep str t))))))
1273 |
1274 | ;;
1275 | ;;; initialize
1276 |
1277 | (defconst quickrun--support-languages
1278 | '("asm" "applescript"
1279 | "c" "c++" "objc" "c#" "perl" "perl6" "ruby" "python" "php" "elisp" "lisp"
1280 | "scheme" "st" "racket" "javascript" "clojure" "erlang" "ocaml" "fsharp"
1281 | "go" "io" "haskell" "java" "d" "markdown" "coffee" "scala" "groovy" "sass"
1282 | "less" "shellscript" "awk" "lua" "rust" "dart" "elixir" "tcl" "jsx"
1283 | "typescript" "fortran" "haml" "swift" "ats" "r" "nim" "nimscript" "fish"
1284 | "julia" "gnuplot" "kotlin" "crystal" "v" "zig")
1285 | "Programming languages and Markup languages supported as default
1286 | by quickrun.el. But you can register your own command for some languages")
1287 |
1288 | (defvar quickrun--command-key-table
1289 | (make-hash-table :test 'equal))
1290 |
1291 | ;;;###autoload
1292 | (defun quickrun-set-default (lang key)
1293 | "Set `key' as default key in programing language `lang'."
1294 | (unless (assoc key quickrun--language-alist)
1295 | (error "%s is not registered" key))
1296 | (puthash lang key quickrun--command-key-table))
1297 |
1298 | ;;;###autoload
1299 | (defun quickrun-select-default ()
1300 | "Update the default."
1301 | (interactive)
1302 | (when-let*
1303 | ((src (buffer-name))
1304 | (lang (or (and src (quickrun--decide-file-type src))
1305 | (quickrun--find-from-major-mode-alist)))
1306 | (default (ht-get quickrun--command-key-table lang))
1307 | (candidates (cl-remove-if-not (lambda (item)
1308 | (string= lang (nth 0 (split-string (car item) "/"))))
1309 | quickrun--language-alist))
1310 | (prompt (format "QuickRun Lang%s: "(if default
1311 | (format " [Default: %s]" default)
1312 | "")))
1313 | (key (completing-read prompt candidates nil nil nil nil default)))
1314 | (quickrun-set-default lang key)))
1315 |
1316 | (defun quickrun--override-command (cmdkey cmd-alist)
1317 | "Not documented."
1318 | (let ((registered (assoc-default cmdkey quickrun--language-alist)))
1319 | (unless registered
1320 | (error (format "'%s' is not registered" cmdkey)))
1321 | (cl-loop for old-param in registered
1322 | do
1323 | (let ((new-value (assoc-default (car old-param) cmd-alist)))
1324 | (when new-value
1325 | (setcdr old-param new-value))))))
1326 |
1327 | ;;;###autoload
1328 | (cl-defun quickrun-add-command (key alist &key default mode override)
1329 | "Not documented."
1330 | (declare (indent defun))
1331 | (cond ((not key) (error "Undefined 1st argument 'key'"))
1332 | ((not alist) (error "Undefined 2nd argument 'command alist'")))
1333 | (if override
1334 | (quickrun--override-command key (copy-alist alist))
1335 | (if (not (assoc :command alist))
1336 | (error "Not found :command parameter in language alist")
1337 | (push (cons key (copy-alist alist)) quickrun--language-alist)))
1338 | (let ((cmd-key (or default key)))
1339 | (when default
1340 | (puthash cmd-key key quickrun--command-key-table))
1341 | (when mode
1342 | (push (cons mode cmd-key) quickrun--major-mode-alist))
1343 | key))
1344 |
1345 | (defun quickrun--find-executable (candidates)
1346 | "Not documented."
1347 | (cl-loop for candidate in candidates
1348 | when (executable-find candidate)
1349 | return candidate))
1350 |
1351 | (defun quickrun--set-command-key (lang candidates)
1352 | "Not documented."
1353 | (quickrun--awhen (quickrun--find-executable candidates)
1354 | (puthash lang (format "%s/%s" lang it) quickrun--command-key-table)))
1355 |
1356 | (defsubst quickrun--c-compiler ()
1357 | "Not documented."
1358 | (cond ((quickrun--windows-p) '("gcc" "clang" "cl"))
1359 | ((eq system-type 'darwin) '("clang" "gcc"))
1360 | (t '("gcc" "clang"))))
1361 |
1362 | (defsubst quickrun--c++-compiler ()
1363 | "Not documented."
1364 | (cond ((quickrun--windows-p) '("g++" "clang++" "cl"))
1365 | ((eq system-type 'darwin) '("clang++" "g++"))
1366 | (t '("g++" "clang++"))))
1367 |
1368 | (defconst quicklang/lang-candidates
1369 | `(("asm" . ("nasm" "masm" "masm64"))
1370 | ("c" . ,(quickrun--c-compiler))
1371 | ("c++" . ,(quickrun--c++-compiler))
1372 | ("c#" . ("dotnet" "mono"))
1373 | ("elisp" . ("emacs" "eask" "eask-g" "eask-c"))
1374 | ("fortran" . ("gfortran"))
1375 | ("javascript" . ("node" "v8" "js" "jrunscript" "cscript" "deno"))
1376 | ("ruby" . ("ruby" "mruby"))
1377 | ("lisp" . ("clisp" "sbcl" "ccl"))
1378 | ("scheme" . ("gosh"))
1379 | ("swift" . ("xcrun" "swift"))
1380 | ("typescript" . ("tsc" "deno"))
1381 | ("markdown" . ("Markdown.pl" "kramdown" "bluecloth" "redcarpet" "pandoc"))
1382 | ("clojure" . ("jark" "clj-env-dir"))
1383 | ("go" . ("go" "gccgo"))
1384 | ("zig" . ("zig" "build")))
1385 | "Candidates of language which has some compilers or interpreters.")
1386 |
1387 | (defun quickrun--init-command-key-table ()
1388 | "Decide command for programing language which has multiple candidates."
1389 | (dolist (lang quickrun--support-languages)
1390 | (puthash lang lang quickrun--command-key-table))
1391 | (cl-loop for (lang . candidates) in quicklang/lang-candidates
1392 | do
1393 | (quickrun--set-command-key lang candidates)))
1394 |
1395 | (quickrun--init-command-key-table)
1396 |
1397 | (defun quickrun--set-executed-file ()
1398 | "Not documented."
1399 | (let* ((buffer-file (buffer-file-name))
1400 | (name (or buffer-file (buffer-name)))
1401 | (use-stdin-file-p (quickrun--use-stdin-file-p))
1402 | orig-file)
1403 | (when (string-match (concat "\\(.+\\)" (quickrun--stdin-file-regexp)) name)
1404 | (setq orig-file (match-string 1 name)))
1405 | (if (and (not buffer-file) (not use-stdin-file-p))
1406 | (setq quickrun--executed-file nil)
1407 | (setq quickrun--executed-file
1408 | (if use-stdin-file-p
1409 | (if (not (file-exists-p orig-file))
1410 | (error "Can't find %s" orig-file)
1411 | orig-file)
1412 | (file-name-nondirectory buffer-file))))))
1413 |
1414 | ;;
1415 | ;;; main
1416 |
1417 | ;;;###autoload
1418 | (defun quickrun (&rest plist)
1419 | "Run commands quickly for current buffer.
1420 |
1421 | With universal prefix argument(C-u), select command-key,
1422 | With double prefix argument(C-u C-u), run in compile-only-mode."
1423 | (interactive)
1424 | (quickrun--set-executed-file)
1425 | (let ((beg (or (plist-get plist :start) (point-min)))
1426 | (end (or (plist-get plist :end) (point-max)))
1427 | (quickrun-option-cmd-alist (or quickrun-option-cmd-alist
1428 | (plist-get plist :source)))
1429 | (quickrun--compile-only-flag (or quickrun--compile-only-flag
1430 | (and (consp current-prefix-arg)
1431 | (= (car current-prefix-arg) 16)))))
1432 | (let ((has-error (catch 'quickrun
1433 | (quickrun--common beg end)
1434 | nil)))
1435 | (when has-error
1436 | (message "%s" has-error)
1437 | (quickrun--remove-temp-files)))))
1438 |
1439 | (defvar quickrun--with-arg--history nil)
1440 |
1441 | ;;;###autoload
1442 | (defun quickrun-select ()
1443 | "Run commands after selecting the backend."
1444 | (interactive)
1445 | (when (quickrun-select-default) (quickrun)))
1446 |
1447 | ;;;###autoload
1448 | (defun quickrun-with-arg (arg)
1449 | "Run commands quickly for current buffer with arguments."
1450 | (interactive
1451 | (list (read-string "QuickRun Arg: " nil 'quickrun--with-arg--history)))
1452 | (let ((quickrun-option-args arg))
1453 | (quickrun)))
1454 |
1455 | (defvar quickrun--last-cmd-key nil)
1456 |
1457 | (defun quickrun--prompt ()
1458 | "Not documented."
1459 | (let* ((default (or quickrun-option-cmdkey quickrun--last-cmd-key))
1460 | (prompt (format "QuickRun Lang%s: "(if default
1461 | (format " [Default: %s]" default)
1462 | ""))))
1463 | (completing-read prompt quickrun--language-alist nil nil nil nil default)))
1464 |
1465 | (defun quickrun--region-command-common (start end)
1466 | "Not documented."
1467 | (deactivate-mark)
1468 | (quickrun :start start :end end))
1469 |
1470 | ;;;###autoload
1471 | (defun quickrun-region (start end)
1472 | "Run commands with specified region."
1473 | (interactive "r")
1474 | (quickrun--region-command-common start end))
1475 |
1476 | ;;;###autoload
1477 | (defun quickrun-replace-region (start end)
1478 | "Run commands with specified region and replace."
1479 | (interactive "r")
1480 | (setq quickrun--original-outputter quickrun-option-outputter)
1481 | (let ((quickrun-option-outputter 'replace))
1482 | (quickrun--region-command-common start end)))
1483 |
1484 | ;;;###autoload
1485 | (defun quickrun-eval-print (start end)
1486 | "Run commands with specified region and replace."
1487 | (interactive "r")
1488 | (setq quickrun--original-outputter quickrun-option-outputter)
1489 | (let ((quickrun-option-outputter 'eval-print))
1490 | (quickrun--region-command-common start end)))
1491 |
1492 | ;;;###autoload
1493 | (defun quickrun-compile-only ()
1494 | "Exec only compilation."
1495 | (interactive)
1496 | (let ((quickrun--compile-only-flag t))
1497 | (quickrun)))
1498 |
1499 | ;;;###autoload
1500 | (defun quickrun-compile-only-select ()
1501 | "Run commands after selecting the backend."
1502 | (interactive)
1503 | (let ((quickrun--compile-only-flag t))
1504 | (quickrun-select)))
1505 |
1506 | ;;;###autoload
1507 | (defun quickrun-shell ()
1508 | "Run commands in shell for interactive programs."
1509 | (interactive)
1510 | (let ((quickrun--run-in-shell t)
1511 | (quickrun-focus-p t)
1512 | (quickrun-timeout-seconds nil))
1513 | (quickrun)))
1514 |
1515 | (defun quickrun--add-remove-files (removed-files)
1516 | "Not documented."
1517 | (let ((abs-paths (mapcar 'expand-file-name (quickrun--mklist removed-files))))
1518 | (setq quickrun--remove-files (append abs-paths quickrun--remove-files))))
1519 |
1520 | (defun quickrun--temp-name (src)
1521 | "Not documented."
1522 | (let* ((extension (file-name-extension src))
1523 | (suffix (or (and extension (concat "." extension)) ""))
1524 | (dir (quickrun--default-directory)))
1525 | (expand-file-name (concat dir (make-temp-name "qr_") suffix))))
1526 |
1527 | (defun quickrun--command-key (src)
1528 | "Not documented."
1529 | (let ((file-type (or (and src (quickrun--decide-file-type src))
1530 | (quickrun--find-from-major-mode-alist)))
1531 | (use-prefix-p (and (consp current-prefix-arg)
1532 | (= (car current-prefix-arg) 4))))
1533 | (or (and use-prefix-p (quickrun--prompt))
1534 | (and quickrun-option-cmd-alist "_user_defined") ;; setting dummy value
1535 | quickrun-option-cmdkey
1536 | (and (not file-type) (quickrun--prompt))
1537 | (gethash file-type quickrun--command-key-table)
1538 | file-type
1539 | (quickrun--prompt))))
1540 |
1541 | (defun quickrun--get-content (start end)
1542 | "Not documented."
1543 | (if (quickrun--use-stdin-file-p)
1544 | (with-current-buffer (find-file-noselect quickrun--executed-file)
1545 | (buffer-substring-no-properties (point-min) (point-max)))
1546 | (buffer-substring-no-properties start end)))
1547 |
1548 | (defun quickrun--copy-region-to-tempfile (start end dst)
1549 | "Copy region to temporary file with START, END and destination (DST)."
1550 | ;; Suppress write file message
1551 | (let ((content (quickrun--get-content start end))
1552 | (codec buffer-file-coding-system))
1553 | (with-temp-file dst
1554 | (set-buffer-file-coding-system codec)
1555 | (insert content))
1556 | (quickrun--add-remove-files dst)))
1557 |
1558 | (defun quickrun--kill-quickrun-buffer ()
1559 | "Kill quickrun buffer."
1560 | (when (get-buffer quickrun--buffer-name)
1561 | (kill-buffer quickrun--buffer-name)))
1562 |
1563 | (defun quickrun--setup-exec-buffer (buf)
1564 | "Not documented."
1565 | (let ((default-dir (quickrun--default-directory)))
1566 | (with-current-buffer buf
1567 | (setq quickrun-option-default-directory default-dir))))
1568 |
1569 | (defun quickrun--use-tempfile-p (cmd-key)
1570 | "Check if use temporary file with CMD-KEY."
1571 | (let ((buffile (buffer-file-name)))
1572 | (unless (or quickrun--compile-only-flag (and buffile (file-remote-p buffile)))
1573 | (let* ((cmdinfo (quickrun--command-info cmd-key))
1574 | (tempfile-param (assoc :tempfile cmdinfo)))
1575 | (if tempfile-param
1576 | (cadr tempfile-param)
1577 | t)))))
1578 |
1579 | (defsubst quickrun--buffer-popup-p ()
1580 | "Not documented."
1581 | (and (not (quickrun--defined-outputter-p quickrun-option-outputter))
1582 | (not quickrun--run-in-shell)))
1583 |
1584 | (defun quickrun--common (start end)
1585 | "Not documented."
1586 | (let* ((orig-src quickrun--executed-file)
1587 | (cmd-key (quickrun--command-key orig-src)))
1588 | (quickrun--set-default-directory cmd-key)
1589 | (unless (local-variable-p 'quickrun--last-cmd-key)
1590 | (make-local-variable 'quickrun--last-cmd-key))
1591 | (setq quickrun--last-cmd-key cmd-key)
1592 |
1593 | (let ((src (quickrun--temp-name (or orig-src ""))))
1594 | (if (quickrun--use-tempfile-p cmd-key)
1595 | (quickrun--copy-region-to-tempfile start end src)
1596 | (setq src orig-src))
1597 | (let ((cmd-info-hash (quickrun--fill-templates cmd-key src)))
1598 | (setq quickrun-timeout-seconds (or quickrun-option-timeout-seconds
1599 | (gethash :timeout cmd-info-hash)
1600 | quickrun-timeout-seconds))
1601 | (quickrun--add-remove-files (gethash :remove cmd-info-hash))
1602 | (unless quickrun-option-outputter
1603 | (setq quickrun-option-outputter (gethash :outputter cmd-info-hash)))
1604 | (cond (quickrun--compile-only-flag
1605 | (let* ((cmd (gethash :compile-only cmd-info-hash))
1606 | (cmd-info (quickrun--command-info cmd-key))
1607 | (compile-conf (assoc-default :compile-conf cmd-info)))
1608 | (unless cmd
1609 | (throw 'quickrun
1610 | (format "%s does not support quickrun-compile-only"
1611 | cmd-key)))
1612 | (quickrun--compilation-start cmd compile-conf)))
1613 | (t
1614 | (let ((buf (get-buffer-create quickrun--buffer-name)))
1615 | (quickrun--setup-exec-buffer buf)
1616 | (quickrun--exec (gethash :exec cmd-info-hash)
1617 | (file-name-nondirectory src) major-mode)
1618 | (when (quickrun--buffer-popup-p)
1619 | (quickrun--pop-to-buffer buf 'quickrun--mode)))))))))
1620 |
1621 | (defun quickrun--without-focus ()
1622 | "Not documented."
1623 | (let ((quickrun-focus-p nil))
1624 | (quickrun)))
1625 |
1626 | ;;;###autoload
1627 | (define-minor-mode quickrun-autorun-mode
1628 | "`quickrun' after saving buffer."
1629 | :init-value nil
1630 | :global nil
1631 | :lighter " QAR"
1632 | (if quickrun-autorun-mode
1633 | (add-hook 'after-save-hook 'quickrun--without-focus nil t)
1634 | (remove-hook 'after-save-hook 'quickrun--without-focus t)))
1635 |
1636 | ;;
1637 | ;;; helm/anything interface
1638 |
1639 | (defconst helm-quickrun--actions
1640 | '(("Run this cmd-key" . quickrun--helm-action-default)
1641 | ("Compile only" . quickrun--helm-compile-only)
1642 | ("Run with shell" . quickrun--helm-action-shell)
1643 | ("Run with argument" . quickrun--helm-run-with-arg)
1644 | ("Replace region" . quickrun--helm-action-replace-region)
1645 | ("Eval and insert as comment" . quickrun--helm-action-eval-print))
1646 | "Not documented.")
1647 |
1648 | (defvar helm-quickrun-source
1649 | `((name . "Choose Command-Key")
1650 | (volatile)
1651 | (candidates . (lambda ()
1652 | (cl-loop for (cmd-key . cmd-info) in quickrun--language-alist
1653 | collect (quickrun--helm-candidate cmd-key cmd-info))))
1654 | (action . ,helm-quickrun--actions))
1655 | "The helm/anything source of `quickrun'.")
1656 |
1657 | (defvar quickrun--helm-history nil)
1658 |
1659 | (defvar helm-quickrun-history-source
1660 | `((name . "Helm Quickrun History")
1661 | (volatile)
1662 | (candidates . quickrun--helm-history)
1663 | (action . ,helm-quickrun--actions))
1664 | "The helm source of `quickrun' history.")
1665 |
1666 | (defun quickrun--helm-candidate (cmd-key cmd-info)
1667 | "Not documented."
1668 | (let ((description (or (assoc-default :description cmd-info) "")))
1669 | (cons (format "%-25s %s" cmd-key description) cmd-key)))
1670 |
1671 | (defun quickrun--helm-update-history (cmd-key)
1672 | "Not documented."
1673 | (setq quickrun--helm-history
1674 | (cons cmd-key
1675 | (delete cmd-key quickrun--helm-history))))
1676 |
1677 | (defun quickrun--helm-action-default (cmd-key)
1678 | "Not documented."
1679 | (quickrun--helm-update-history cmd-key)
1680 | (let ((quickrun-option-cmdkey cmd-key)
1681 | start end)
1682 | (if (use-region-p)
1683 | (setq start (region-beginning) end (region-end))
1684 | (setq start (point-min) end (point-max)))
1685 | (quickrun-region start end)))
1686 |
1687 | (defun quickrun--helm-run-with-arg (cmd-key)
1688 | "Not documented."
1689 | (quickrun--helm-update-history cmd-key)
1690 | (let ((quickrun-option-cmdkey cmd-key))
1691 | (call-interactively 'quickrun-with-arg)))
1692 |
1693 | (defun quickrun--helm-action-shell (cmd-key)
1694 | "Not documented."
1695 | (quickrun--helm-update-history cmd-key)
1696 | (let ((quickrun-option-cmdkey cmd-key))
1697 | (quickrun-shell)))
1698 |
1699 | (defun quickrun--helm-compile-only (cmd-key)
1700 | "Not documented."
1701 | (quickrun--helm-update-history cmd-key)
1702 | (let ((quickrun-option-cmdkey cmd-key))
1703 | (quickrun-compile-only)))
1704 |
1705 | (defun quickrun--helm-action-replace-region (cmd-key)
1706 | "Not documented."
1707 | (quickrun--helm-update-history cmd-key)
1708 | (let ((quickrun-option-cmdkey cmd-key))
1709 | (quickrun-replace-region (region-beginning) (region-end))))
1710 |
1711 | (defun quickrun--helm-action-eval-print (cmd-key)
1712 | "Not documented."
1713 | (quickrun--helm-update-history cmd-key)
1714 | (let ((quickrun-option-cmdkey cmd-key))
1715 | (quickrun-eval-print (region-beginning) (region-end))))
1716 |
1717 | ;;;###autoload
1718 | (defun anything-quickrun ()
1719 | "Run quickrun with `anything'."
1720 | (interactive)
1721 | (unless (featurep 'anything)
1722 | (error "Anything is not installed"))
1723 | (anything helm-quickrun-source))
1724 |
1725 | ;;;###autoload
1726 | (defun helm-quickrun ()
1727 | "Run quickrun with `helm'."
1728 | (interactive)
1729 | (unless (featurep 'helm)
1730 | (error "Helm is not installed"))
1731 | (let ((sources (if quickrun--helm-history
1732 | '(helm-quickrun-history-source helm-quickrun-source)
1733 | '(helm-quickrun-source))))
1734 | (helm :sources sources :buffer "*helm quickrun*")))
1735 |
1736 | (provide 'quickrun)
1737 | ;;; quickrun.el ends here
1738 |
--------------------------------------------------------------------------------
/sample/Sample.java:
--------------------------------------------------------------------------------
1 | public class Sample {
2 | public static void main (String [] args) {
3 | System.out.println("hello Java");
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/sample/sample-fail-colorize.coffee:
--------------------------------------------------------------------------------
1 | aa =
2 | aa: 10
3 | a.b: 20
4 |
--------------------------------------------------------------------------------
/sample/sample.R:
--------------------------------------------------------------------------------
1 |
2 | print("Here is a plot generated with R:")
3 | X11()
4 | plot(1:10, pch=1:10)
5 | Sys.sleep(2)
6 | print("Bye!")
7 |
--------------------------------------------------------------------------------
/sample/sample.awk:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env awk
2 | BEGIN {
3 | print "Hello awk"
4 | }
5 |
--------------------------------------------------------------------------------
/sample/sample.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function helloworld () {
4 | printf "Hello Bash $1\n"
5 | }
6 |
7 | helloworld "quickrun"
8 |
--------------------------------------------------------------------------------
/sample/sample.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, char *argv[])
4 | {
5 | printf("hello C\n");
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/sample/sample.clj:
--------------------------------------------------------------------------------
1 | (defn helloworld []
2 | (println "Hello Clojure"))
3 |
4 | (helloworld)
5 |
--------------------------------------------------------------------------------
/sample/sample.coffee:
--------------------------------------------------------------------------------
1 | hello = ->
2 | console.log("Hello CoffeeScript!")
3 |
4 | hello()
5 |
--------------------------------------------------------------------------------
/sample/sample.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, char *argv[])
4 | {
5 | std::cout << "hello C++" << std::endl;
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/sample/sample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | public class HelloWorld
4 | {
5 | static public void Main ()
6 | {
7 | Console.WriteLine ("Hello Mono Quickrun");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/sample/sample.d:
--------------------------------------------------------------------------------
1 | import std.stdio;
2 | void main()
3 | {
4 | writeln("Hello, D language!");
5 | }
6 |
--------------------------------------------------------------------------------
/sample/sample.dart:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | say(name) {
3 | print('Hello Dart, $name');
4 | }
5 | }
6 |
7 | main() {
8 | var hello = new HelloWorld();
9 | hello.say("quickrun.el!");
10 | }
11 |
--------------------------------------------------------------------------------
/sample/sample.el:
--------------------------------------------------------------------------------
1 | (defun hello-world (arg)
2 | (princ (format "Hello Emacs lisp: %s\n" arg)))
3 |
4 | (hello-world "Emacs")
5 |
--------------------------------------------------------------------------------
/sample/sample.erl:
--------------------------------------------------------------------------------
1 | -module(demo).
2 | -export([main/1]).
3 |
4 | main(_Args) ->
5 | io:format("Hello, Erlang\n", []).
6 |
--------------------------------------------------------------------------------
/sample/sample.ex:
--------------------------------------------------------------------------------
1 | defmodule Hello do
2 | def world do
3 | Erlang.io.format("Hello Elixer.~n", [])
4 | end
5 | end
6 | Hello.world
7 |
--------------------------------------------------------------------------------
/sample/sample.f95:
--------------------------------------------------------------------------------
1 | program hello
2 | print *, 'Hello Fortran95!'
3 | end program hello
4 |
--------------------------------------------------------------------------------
/sample/sample.fish:
--------------------------------------------------------------------------------
1 | function say_hello
2 | echo Hello $argv
3 | end
4 |
5 | say_hello "everybody!"
6 |
--------------------------------------------------------------------------------
/sample/sample.fsx:
--------------------------------------------------------------------------------
1 | printfn "Hello World to F# language "
2 |
--------------------------------------------------------------------------------
/sample/sample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Printf("hello, Go language\n")
7 | }
8 |
--------------------------------------------------------------------------------
/sample/sample.groovy:
--------------------------------------------------------------------------------
1 | def helloworld() {
2 | println("Hello Groovy")
3 | }
4 |
5 | helloworld()
6 |
--------------------------------------------------------------------------------
/sample/sample.haml:
--------------------------------------------------------------------------------
1 | !!! 5
2 | %html
3 | %head
4 | %title= "QuickRun HAML"
5 | %body
6 | %h1= "quickrun.el support HAML"
7 |
--------------------------------------------------------------------------------
/sample/sample.hs:
--------------------------------------------------------------------------------
1 | main :: IO()
2 | main = putStrLn "Hello Haskell!"
3 |
--------------------------------------------------------------------------------
/sample/sample.io:
--------------------------------------------------------------------------------
1 | helloworld := method(
2 | writeln("Hello Io language")
3 | )
4 | helloworld(hello)
5 |
--------------------------------------------------------------------------------
/sample/sample.jl:
--------------------------------------------------------------------------------
1 | function hello_world(name)
2 | print(string("hello ", name, "\n"))
3 | end
4 |
5 | hello_world("quickrun")
6 |
--------------------------------------------------------------------------------
/sample/sample.jsx:
--------------------------------------------------------------------------------
1 | class HelloEditor {
2 | var _editors : string[];
3 |
4 | function constructor () {
5 | }
6 |
7 | function constructor (editors : string[]) {
8 | this._editors = editors;
9 | }
10 |
11 | function hello () : void {
12 | this._editors.forEach(function(e) {
13 | log e;
14 | });
15 | }
16 | }
17 |
18 | class _Main {
19 | static function main(args :string[]) : void {
20 | var he = new HelloEditor(['Emacs', 'JSX']);
21 | he.hello();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/sample/sample.less:
--------------------------------------------------------------------------------
1 | @color: #4D926F;
2 |
3 | #header {
4 | color: @color;
5 | }
6 | h2 {
7 | color: @color;
8 | }
9 |
--------------------------------------------------------------------------------
/sample/sample.lisp:
--------------------------------------------------------------------------------
1 | (defun hello-world ()
2 | (format t "hello CommonLisp"))
3 |
4 | (hello-world)
5 |
--------------------------------------------------------------------------------
/sample/sample.lua:
--------------------------------------------------------------------------------
1 | function helloWorld()
2 | print("Hello, Lua")
3 | end
4 |
5 | helloWorld()
6 |
--------------------------------------------------------------------------------
/sample/sample.m:
--------------------------------------------------------------------------------
1 | #ifdef __APPLE__
2 | #import
3 | #import
4 | #else
5 | #import
6 | #import
7 | #endif
8 |
9 | #ifdef __APPLE__
10 | @interface HelloClass : NSObject
11 | #else
12 | @interface HelloClass : Object
13 | #endif
14 | - (void)helloWorld;
15 | @end
16 |
17 | @implementation HelloClass
18 | - (void)helloWorld {
19 | printf("Hello Objective C!\n");
20 | }
21 | @end
22 |
23 | int main() {
24 | id obj = [HelloClass alloc];
25 | [obj helloWorld];
26 | return 0;
27 | }
28 |
--------------------------------------------------------------------------------
/sample/sample.md:
--------------------------------------------------------------------------------
1 | # head1
2 | ## head2
3 | ### head3
4 |
5 | [This is Link](http://example.com "sample")
6 |
--------------------------------------------------------------------------------
/sample/sample.ml:
--------------------------------------------------------------------------------
1 | print_endline "Hello Ocaml!";;
2 |
--------------------------------------------------------------------------------
/sample/sample.nim:
--------------------------------------------------------------------------------
1 | # Hello world program
2 |
3 | echo "Hello World"
4 |
--------------------------------------------------------------------------------
/sample/sample.php:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/sample/sample.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "This is Perl test\n";
6 |
7 | sub add {
8 | $_[0] + $_[1];
9 | }
10 |
11 | print add(100, 200), "\n";
12 |
--------------------------------------------------------------------------------
/sample/sample.pl6:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl6
2 |
3 | class Sample {
4 | method hello(Str $name) {
5 | say "Hello $name";
6 | }
7 | }
8 |
9 | Sample.new.hello("world");
10 |
--------------------------------------------------------------------------------
/sample/sample.plt:
--------------------------------------------------------------------------------
1 | set samples 20
2 | set isosamples 21
3 | set xlabel "X axis"
4 | set ylabel "Y axis"
5 | set zlabel "Z " offset 1, 0
6 | set view 60, 30, 0.85, 1.1
7 | set key at screen 1.0, 0.9
8 | set style textbox opaque noborder margins 0.5, 0.5
9 |
10 | set title "contour plot"
11 | set contour
12 | splot x*y
13 |
--------------------------------------------------------------------------------
/sample/sample.pod:
--------------------------------------------------------------------------------
1 | # -*- mode:fundamental -*-
2 | =encoding utf-8
3 |
4 | =head1 NAME
5 |
6 | quickrun.el - Emacs edition of quickrun.vim
7 |
8 | =head1 SYNOPSIS
9 |
10 | (add-to-list 'quickrun-file-alist '("\\.pod$" . "pod"))
11 | (quickrun-add-command "pod"
12 | '((:command . "perldoc")
13 | (:exec . "%c -T -F %s"))
14 | :mode 'pod-mode)
15 |
16 | =head1 DESCRIPTION
17 |
18 | quickrun.el run command quickly for (programming|markup) language.
19 |
20 | =head1 AUTHOR
21 |
22 | Syohei YOSHIDA
23 |
24 | =cut
25 |
--------------------------------------------------------------------------------
/sample/sample.py:
--------------------------------------------------------------------------------
1 | def helloworld (arg):
2 | print("Hello Python " + arg)
3 |
4 | helloworld("quickrun.el")
5 |
--------------------------------------------------------------------------------
/sample/sample.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # -*- coding: utf-8 -*-
3 |
4 | puts "hello Ruby"
5 |
--------------------------------------------------------------------------------
/sample/sample.rkt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env racket
2 | #lang racket/base
3 |
4 | (define (greeting name)
5 | (printf "Hello Racket ~a\n" name))
6 |
7 | (greeting "quickrun")
8 |
--------------------------------------------------------------------------------
/sample/sample.rs:
--------------------------------------------------------------------------------
1 | use std;
2 |
3 | fn main() {
4 | std::io::println("Hello world in Rust");
5 | }
6 |
--------------------------------------------------------------------------------
/sample/sample.sass:
--------------------------------------------------------------------------------
1 | .link
2 | :color #0080DD
3 | .link:hover
4 | :color blue
5 |
6 | //
7 | // Local Variables:
8 | // quickrun-option-outputter: (lambda () (css-mode))
9 | // End:
10 | //
11 |
--------------------------------------------------------------------------------
/sample/sample.scala:
--------------------------------------------------------------------------------
1 | println("Hello Scala")
2 |
--------------------------------------------------------------------------------
/sample/sample.scm:
--------------------------------------------------------------------------------
1 | (define (test)
2 | (print "hello Scheme"))
3 | (test)
4 |
--------------------------------------------------------------------------------
/sample/sample.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | printf "Hello /bin/sh\n"
3 |
--------------------------------------------------------------------------------
/sample/sample.swift:
--------------------------------------------------------------------------------
1 | func helloWorld(name : String) -> String {
2 | return "Hello \(name)"
3 | }
4 |
5 | print(helloWorld("quickrun"))
6 |
--------------------------------------------------------------------------------
/sample/sample.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 |
5 | my $var = "quickrun";
6 | is "quickrun", $var, "setting string 'quickrun'";
7 |
8 | like $var, qr/quick/, "var looks like 'quick'";
9 |
10 | ok undef, 'error test';
11 |
12 | done_testing;
13 |
14 | __END__
15 |
16 | (progn
17 | (add-to-list 'quickrun-file-alist '("\\.t$" . "prove"))
18 | (quickrun-add-command "prove" '((:command . "prove") (:exec . "%c -v %s"))))
19 |
--------------------------------------------------------------------------------
/sample/sample.tcl:
--------------------------------------------------------------------------------
1 | fconfigure stdout -translation lf
2 | fconfigure stderr -translation lf
3 |
4 | set foo "Hello"
5 | set bar "Quickrun"
6 | puts "$foo, $bar"
7 |
--------------------------------------------------------------------------------
/sample/sample.ts:
--------------------------------------------------------------------------------
1 | class Greeter {
2 | greeting: string;
3 | constructor (message: string) {
4 | this.greeting = message;
5 | }
6 | greet() {
7 | return "Hello " + this.greeting;
8 | }
9 | }
10 |
11 | var greeter = new Greeter("world");
12 | console.log(greeter.greet())
13 |
--------------------------------------------------------------------------------
/sample/sample_as_function.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print catfile("/home", "user", "tmp", "perl"), "\n";
6 | print getcwd(), "\n";
7 |
8 | __END__
9 |
10 | (defun exec-perl ()
11 | (interactive)
12 | (quickrun :source '((:command . "perl")
13 | (:default-directory . "/home/syohei/tmp")
14 | (:exec . ("perl -MCwd -MFile::Spec::Functions %s")))))
15 |
--------------------------------------------------------------------------------
/sample/sample_buffer_local_var.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | printf("cos(3.14) = %g\n", cos(3.14));
7 | return 0;
8 | }
9 |
10 | /*
11 | Local Variables:
12 | quickrun-option-cmdopt: "-lm"
13 | End:
14 | */
15 |
--------------------------------------------------------------------------------
/sample/sample_buffer_local_var2.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | binmode STDOUT, ":utf8";
6 |
7 | for my $arg (@ARGV) {
8 | if (looks_like_number($arg) && $arg == 72) {
9 | print "くっ\n";
10 | }
11 | }
12 |
13 | # Local Variables:
14 | # quickrun-option-cmdopt: "-MScalar::Util=looks_like_number -Mutf8"
15 | # quickrun-option-args: "765 IdleM@ster 72 "
16 | # End:
17 |
--------------------------------------------------------------------------------
/sample/sample_c11.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | /*
6 | (quickrun-add-command "c++/c11"
7 | '((:command . "g++")
8 | (:exec . ("%c -std=c++11 %o -o %n %s"
9 | "%n %a"))
10 | (:remove . ("%n")))
11 | :default "c++")
12 | */
13 |
14 | int main ()
15 | {
16 | std::vector lst = { "a", "b", "c", "d" };
17 |
18 | for (auto x : lst){
19 | std::cout << "[" << x << "]" << std::endl;
20 | }
21 |
22 | return 0;
23 | }
24 |
--------------------------------------------------------------------------------
/sample/sample_color.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 | use strict;
3 | use warnings;
4 |
5 | use Term::ANSIColor qw(:constants);
6 |
7 | print RED BOLD "This is RED and BOLD\n", RESET;
8 | print GREEN UNDERSCORE "This is GREEN and UNDERSCORE\n", RESET;
9 | print BOLD ON_BLUE "This is BACKGROUND COLOR\n", RESET;
10 |
--------------------------------------------------------------------------------
/sample/sample_compile_error.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, char *argv[])
4 | {
5 | printf("hello world\n")
6 | return 0;
7 | }
8 |
9 | /*
10 | Local Variables:
11 | quickrun-option-command: "clang"
12 | End:
13 | */
14 |
--------------------------------------------------------------------------------
/sample/sample_endless_loop.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function endlessLoop () {
4 | local step=1
5 | while true
6 | do
7 | printf "Endless loop step %d\n" $step
8 | ((step+=1))
9 | sleep 1
10 | done
11 | }
12 |
13 | endlessLoop
14 |
--------------------------------------------------------------------------------
/sample/sample_interactive.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main (void)
5 | {
6 | char name[128];
7 | int age;
8 |
9 | printf("Your name >> ");
10 | fgets(name, 128, stdin);
11 |
12 | printf("Your age >> ");
13 | scanf("%d", &age);
14 |
15 | printf("Your name is %s", name);
16 | printf("Your age is %d\n", age);
17 | return 0;
18 | }
19 |
--------------------------------------------------------------------------------
/sample/sample_jrunscript.js:
--------------------------------------------------------------------------------
1 | function helloworld (arg) {
2 | print(arg + "\n");
3 | }
4 |
5 | helloworld("Hello jrunscript");
6 |
--------------------------------------------------------------------------------
/sample/sample_js.js:
--------------------------------------------------------------------------------
1 | (function (arg) {
2 | print(arg);
3 | }("Hello World"));
4 |
--------------------------------------------------------------------------------
/sample/sample_node.js:
--------------------------------------------------------------------------------
1 | console.log("hello node.js");
2 |
--------------------------------------------------------------------------------
/sample/sample_noshebang.pl:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 |
4 | print "hello world\n";
5 |
--------------------------------------------------------------------------------
/sample/sample_outputter_browser.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print <<'...';
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Quickrun
17 |
21 |
22 |
23 | ...
24 |
25 | #
26 | # Local Variables:
27 | # quickrun-option-outputter: browser
28 | # End:
29 | #
30 |
--------------------------------------------------------------------------------
/sample/sample_outputter_buffer.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "I love Emacs and Vim\n";
6 | print "You love Emacs and Vim\n";
7 | print "We love Emacs and emacs\n";
8 |
9 | #
10 | # Local Variables:
11 | # quickrun-option-outputter: buffer:*outputter-test*
12 | # End:
13 | #
14 |
--------------------------------------------------------------------------------
/sample/sample_outputter_file.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "I love emacs\n";
6 | print "You love emacs\n";
7 | print "We love emacs\n";
8 |
9 | #
10 | # Local Variables:
11 | # quickrun-option-outputter: file:qr_test.txt
12 | # End:
13 | #
14 |
--------------------------------------------------------------------------------
/sample/sample_outputter_multi.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "I love Emacs and Vim\n";
6 | print "You love Emacs and Vim\n";
7 | print "We love Emacs and emacs\n";
8 |
9 | #
10 | # Local Variables:
11 | # quickrun-option-outputter: (multi . (buffer:*multi1* file:multi.txt variable:multi-var))
12 | # End:
13 | #
14 |
--------------------------------------------------------------------------------
/sample/sample_outputter_null.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "I love Common Lisp\n";
6 |
7 | #
8 | # Local Variables:
9 | # quickrun-option-outputter: null
10 | # End:
11 | #
12 |
--------------------------------------------------------------------------------
/sample/sample_outputter_variable.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "I love Perl too\n";
6 |
7 | #
8 | # Local Variables:
9 | # quickrun-option-outputter: variable:test-variable
10 | # End:
11 | #
12 |
--------------------------------------------------------------------------------
/sample/sample_set_default_directory.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | print "hello\n";
6 |
7 | #
8 | # Local Variables:
9 | # quickrun-option-cmd-alist: ((:command . "sh")
10 | # (:exec . ("sh -c 'ls -l'"))
11 | # (:default-directory . "/tmp"))
12 | # End:
13 | #
14 |
--------------------------------------------------------------------------------
/sample/sample_spec.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | require 'rspec'
3 |
4 | def add(a, b)
5 | a + b
6 | end
7 |
8 | def sub(a, b)
9 | a * b
10 | end
11 |
12 | describe "Test func" do
13 | it "one plus one" do
14 | (add(1,1)==2).should be_true
15 | end
16 | it "one minus one" do
17 | (sub(1,1)==0).should be_true
18 | end
19 | end
20 |
21 | #
22 | # Local Variables:
23 | # quickrun-option-cmd-alist: ((:command . "rspec")
24 | # (:exec . "%c -c %s"))
25 | # End:
26 | #
27 |
--------------------------------------------------------------------------------
/sample/sample_timeout.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(void)
5 | {
6 | int i;
7 |
8 | for (i = 0; i < 5; i++) {
9 | printf("hello %d\n", i);
10 | sleep(1);
11 | }
12 |
13 | return 0;
14 | }
15 |
--------------------------------------------------------------------------------
/sample/sample_timeout.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | sleep 20;
6 | print "too sleep\n";
7 |
--------------------------------------------------------------------------------
/sample/sample_user_defined.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main (int argc, char *argv[])
6 | {
7 | std::vector lst = { "a", "b", "c", "d" };
8 |
9 | for (auto x : lst){
10 | std::cout << "[" << x << "]" << std::endl;
11 | }
12 |
13 | for (auto i = 1; i < argc; i++){
14 | std::cout << "[" << argv[i] << "]" << std::endl;
15 | }
16 |
17 | return 0;
18 | }
19 |
20 | /*
21 | Local Variables:
22 | quickrun-option-cmd-alist: ((:command . "g++")
23 | (:exec . ("%c -std=c++11 -o %n %s"
24 | "%n apple orange melon"))
25 | (:outputter .
26 | (lambda ()
27 | (highlight-phrase "\\(\\[\\|\\]\\)" "hi-green")))
28 | (:remove . ("%n")))
29 | End:
30 | */
31 |
--------------------------------------------------------------------------------
/sample/sample_utf8_jp.scala:
--------------------------------------------------------------------------------
1 | println("こんにちわ Scala");
2 |
--------------------------------------------------------------------------------
/sample/sample_with_arg.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(int argc, char *argv[])
4 | {
5 | printf("hello world %s %s\n", argv[1], argv[2]);
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/sample/sample_with_arg.pl:
--------------------------------------------------------------------------------
1 | #!perl
2 | use strict;
3 | use warnings;
4 |
5 | my $name = shift;
6 | print "my name is $name\n";
7 |
--------------------------------------------------------------------------------
/sample/sample_write_stderr.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 | use strict;
3 | use warnings;
4 |
5 | use Data::Dumper;
6 |
7 | die Dumper({ name => 'Vim', age => 30, hobby => 'driving' });
8 |
--------------------------------------------------------------------------------
/test/test-quickrun.el:
--------------------------------------------------------------------------------
1 | ;;; test-quickrun.el --- test for quickrun
2 |
3 | ;; Copyright (C) 2017 by Syohei YOSHIDA
4 |
5 | ;; Author: Syohei YOSHIDA
6 |
7 | ;; This program is free software; you can redistribute it and/or modify
8 | ;; it under the terms of the GNU General Public License as published by
9 | ;; the Free Software Foundation, either version 3 of the License, or
10 | ;; (at your option) any later version.
11 |
12 | ;; This program is distributed in the hope that it will be useful,
13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ;; GNU General Public License for more details.
16 |
17 | ;; You should have received a copy of the GNU General Public License
18 | ;; along with this program. If not, see .
19 |
20 | ;;; Commentary:
21 |
22 | ;;; Code:
23 |
24 | (require 'ert)
25 | (require 'quickrun)
26 |
27 | (ert-deftest quickrun:exec-quickrun ()
28 | "Exec `quickrun'"
29 | (let ((buf (find-file-noselect "sample/sample.py")))
30 | (with-current-buffer buf
31 | (quickrun))
32 | ;; quickrun is async function
33 | (sleep-for 1)
34 | (with-current-buffer "*quickrun*"
35 | (let ((str (buffer-substring-no-properties (point-min) (point-max))))
36 | (should (string= "Hello Python quickrun.el\n" str))))
37 | (sleep-for 1)))
38 |
39 | (ert-deftest quickrun:add-command ()
40 | "Add new command"
41 | (quickrun-add-command "-test"
42 | '((:command . "test foo")
43 | (:description . "test description")))
44 | (let ((params (assoc-default "-test" quickrun--language-alist)))
45 | (should params)
46 | (let ((command (assoc-default :command params))
47 | (desc (assoc-default :description params)))
48 | (should (string= command "test foo"))
49 | (should (string= desc "test description")))))
50 |
51 | (ert-deftest quickrun:override-configuration ()
52 | "Override registerd command"
53 | (quickrun-add-command "c/gcc"
54 | '((:command . "clang")
55 | (:description . "Compile clang"))
56 | :override t)
57 | (let* ((params (assoc-default "c/gcc" quickrun--language-alist))
58 | (command (assoc-default :command params)))
59 | (should (string= command "clang"))))
60 |
61 | (ert-deftest quickrun:use-tempfile-p ()
62 | "Whether use temporary file or not."
63 | (quickrun-add-command "tempfile0" '((:command . "tempfile0") (:tempfile . t)))
64 | (let ((use-tempfile (quickrun--use-tempfile-p "tempfile0")))
65 | (should use-tempfile))
66 |
67 | (quickrun-add-command "tempfile1" '((:command . "tempfile1") (:tempfile . nil)))
68 | (let ((use-tempfile (quickrun--use-tempfile-p "tempfile1")))
69 | (should-not use-tempfile))
70 |
71 | ;; use temporary file if :tempfile paramter is not specified
72 | (quickrun-add-command "tempfile2" '((:command . "tempfile2")))
73 | (let ((use-tempfile (quickrun--use-tempfile-p "tempfile2")))
74 | (should use-tempfile))
75 |
76 | (let* ((quickrun--compile-only-flag t)
77 | (use-tempfile (quickrun--use-tempfile-p "hoge")))
78 | (should-not use-tempfile)))
79 |
80 | (ert-deftest quickrun:user-manually-terminates-program ()
81 | "Users are able to manually terminate the program with no errors."
82 | (with-current-buffer (find-file-noselect "sample/sample_endless_loop.bash")
83 | (quickrun))
84 | (sleep-for 1)
85 | (condition-case err
86 | (let ((buf (get-buffer "*quickrun*"))
87 | (inhibit-message t))
88 | (set-process-query-on-exit-flag (get-buffer-process buf) nil)
89 | (kill-buffer buf)
90 | (sleep-for 1)) ; Wait for the sentinel.
91 | (wrong-type-argument
92 | (quickrun--remove-temp-files)
93 | (signal 'error "Cannot access a deleted buffer"))))
94 |
95 | ;;; test-quickrun.el ends here
96 |
--------------------------------------------------------------------------------