aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--core/locale.conf4
-rw-r--r--core/locales/locale.ar.conf4
-rw-r--r--core/locales/locale.de.conf4
-rw-r--r--core/locales/locale.es.conf4
-rw-r--r--core/locales/locale.fr.conf4
-rw-r--r--core/locales/locale.it.conf4
-rw-r--r--core/locales/locale.pl.conf4
-rw-r--r--core/locales/locale.ru.conf4
-rw-r--r--core/locales/locale.sv.conf4
-rw-r--r--core/locales/locale.zh.conf4
-rw-r--r--docs/api.md42
-rw-r--r--docs/manual.md45
-rw-r--r--modules/lua/ta_api5
-rw-r--r--modules/lua/ta_tags3
-rw-r--r--modules/textadept/keys.lua8
-rw-r--r--modules/textadept/menu.lua1
-rw-r--r--modules/textadept/run.lua60
-rw-r--r--test/modules/textadept/run/test.lua1
-rw-r--r--test/test.lua12
19 files changed, 173 insertions, 44 deletions
diff --git a/core/locale.conf b/core/locale.conf
index 18a62e2b..5deeac29 100644
--- a/core/locale.conf
+++ b/core/locale.conf
@@ -235,7 +235,9 @@ For Run: = For Run:
For Compile: = For Compile:
# Menu item for building the current project.
Build = Buil_d
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = S_top
# Menu items for navigating through recognized shell command errors.
Next Error = _Next Error
diff --git a/core/locales/locale.ar.conf b/core/locales/locale.ar.conf
index e894445e..17e524e1 100644
--- a/core/locales/locale.ar.conf
+++ b/core/locales/locale.ar.conf
@@ -235,7 +235,9 @@ For Run: = For Run:
For Compile: = For Compile:
# Menu item for building the current project.
Build = ا_بْن ِ
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = قِفْ
# Menu items for navigating through recognized shell command errors.
Next Error = اذهب لل_خطأ التالي
diff --git a/core/locales/locale.de.conf b/core/locales/locale.de.conf
index d73ca229..983bcbe1 100644
--- a/core/locales/locale.de.conf
+++ b/core/locales/locale.de.conf
@@ -235,7 +235,9 @@ For Run: = Zum Ausführen:
For Compile: = Zum Kompilieren:
# Menu item for building the current project.
Build = Bauen
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = Anhalten
# Menu items for navigating through recognized shell command errors.
Next Error = Nächster Fehler
diff --git a/core/locales/locale.es.conf b/core/locales/locale.es.conf
index 273b90ca..b2496e97 100644
--- a/core/locales/locale.es.conf
+++ b/core/locales/locale.es.conf
@@ -235,7 +235,9 @@ For Run: = Al ejecutar:
For Compile: = Al compilar:
# Menu item for building the current project.
Build = Co_nstruir
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = _Detener
# Menu items for navigating through recognized shell command errors.
Next Error = Error sig_uiente
diff --git a/core/locales/locale.fr.conf b/core/locales/locale.fr.conf
index f3afccfa..f8c8de51 100644
--- a/core/locales/locale.fr.conf
+++ b/core/locales/locale.fr.conf
@@ -236,7 +236,9 @@ For Run: = Pour lancer:
For Compile: = Por compiler:
# Menu item for building the current project.
Build = C_onstruire
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = _Arrêter
# Menu items for navigating through recognized shell command errors.
Next Error = Erreur _suivante
diff --git a/core/locales/locale.it.conf b/core/locales/locale.it.conf
index d9c508a1..9454a395 100644
--- a/core/locales/locale.it.conf
+++ b/core/locales/locale.it.conf
@@ -235,7 +235,9 @@ For Run: = Per l'esecuzione:
For Compile: = Per la compilazione:
# Menu item for building the current project.
Build = C_ostruisci
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = _Arresta
# Menu items for navigating through recognized shell command errors.
Next Error = Errore s_eguente
diff --git a/core/locales/locale.pl.conf b/core/locales/locale.pl.conf
index a33b1d69..7b4430de 100644
--- a/core/locales/locale.pl.conf
+++ b/core/locales/locale.pl.conf
@@ -236,7 +236,9 @@ For Run: = Dla uruchomienia:
For Compile: = Dla kompilacji:
# Menu item for building the current project.
Build = Z_buduj
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = Pr_zerwij
# Menu items for navigating through recognized shell command errors.
Next Error = _Następny błąd
diff --git a/core/locales/locale.ru.conf b/core/locales/locale.ru.conf
index 476d0f63..f3ca3446 100644
--- a/core/locales/locale.ru.conf
+++ b/core/locales/locale.ru.conf
@@ -235,7 +235,9 @@ For Run: = Параметры запуска:
For Compile: = Параметры сборки:
# Menu item for building the current project.
Build = С_обрать
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = Ос_тановить
# Menu items for navigating through recognized shell command errors.
Next Error = Следующая Ошибка
diff --git a/core/locales/locale.sv.conf b/core/locales/locale.sv.conf
index f6f01d17..883abf2b 100644
--- a/core/locales/locale.sv.conf
+++ b/core/locales/locale.sv.conf
@@ -235,7 +235,9 @@ For Run: = För Kör:
For Compile: = För Kompilera:
# Menu item for building the current project.
Build = B_ygg
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = Avbry_t
# Menu items for navigating through recognized shell command errors.
Next Error = _Nästa fel
diff --git a/core/locales/locale.zh.conf b/core/locales/locale.zh.conf
index 54476596..648e3968 100644
--- a/core/locales/locale.zh.conf
+++ b/core/locales/locale.zh.conf
@@ -235,7 +235,9 @@ For Run: = 运行参数:
For Compile: = 编译参数:
# Menu item for building the current project.
Build = 构建(_D)
-# Menu item for stopping a run, compile, or build shell command.
+# Menu item for running the current project's tests/test suite.
+Run tests = R_un tests
+# Menu item for stopping a run, compile, build, or test shell command.
Stop = 停止(_T)
# Menu items for navigating through recognized shell command errors.
Next Error = 下一个错误(_N)
diff --git a/docs/api.md b/docs/api.md
index db0b6dbe..7d225a0d 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -7009,6 +7009,7 @@ Ctrl+R |⌘R |^R |Run
Ctrl+Shift+R |⌘⇧R |M-^R |Compile
Ctrl+Shift+A |⌘⇧A |None |Set Arguments...
Ctrl+Shift+B |⌘⇧B |M-^B |Build
+Ctrl+Shift+T |⌘⇧T |M-^T |Run tests
Ctrl+Shift+X |⌘⇧X |M-^X |Stop
Ctrl+Alt+E |^⌘E |M-X |Next Error
Ctrl+Alt+Shift+E|^⌘⇧E |M-S-X |Previous Error
@@ -7250,7 +7251,8 @@ number.
Compile and run source code files with Textadept.
[Language modules](#compile-and-run) may tweak the `compile_commands`,
`run_commands`, and `error_patterns` tables for particular languages.
-The user may tweak `build_commands` for particular projects.
+The user may tweak `build_commands` and `test_commands` for particular
+projects.
### Fields defined by `textadept.run`
@@ -7299,6 +7301,16 @@ Emitted when executing a language's run shell command.
* `ext_or_lexer`: The file extension or lexer name associated with the
executed run command.
+<a id="events.TEST_OUTPUT"></a>
+#### `events.TEST_OUTPUT` (string)
+
+Emitted when executing a project's shell command for running tests.
+ By default, output is printed to the message buffer. In order to override
+ this behavior, connect to the event with an index of `1` and return `true`.
+ Arguments:
+
+ * `output`: A line of string output from the command.
+
<a id="textadept.run.run_in_background"></a>
#### `textadept.run.run_in_background` (bool)
@@ -7417,6 +7429,25 @@ See also:
Stops the currently running process, if any.
+<a id="textadept.run.test"></a>
+#### `textadept.run.test`(*root\_directory*)
+
+Runs tests for the project whose root path is *root_directory* or the current
+project using the shell command from the `test_commands` table.
+The current project is determined by either the buffer's filename or the
+current working directory.
+Emits `TEST_OUTPUT` events.
+
+Parameters:
+
+* *`root_directory`*: The path to the project to run tests for. The default
+ value is the current project.
+
+See also:
+
+* [`textadept.run.test_commands`](#textadept.run.test_commands)
+* [`events`](#events)
+
### Tables defined by `textadept.run`
@@ -7475,6 +7506,15 @@ Functions may also return a working directory and process environment table
to operate in. By default, the working directory is the current file's parent
directory and the environment is Textadept's environment.
+<a id="textadept.run.test_commands"></a>
+#### `textadept.run.test_commands`
+
+Map of project root paths to their associated "test" shell command line
+strings or functions that return such strings.
+Functions may also return a working directory and process environment table
+to operate in. By default, the working directory is the project's root
+directory and the environment is Textadept's environment.
+
---
<a id="textadept.session"></a>
## The `textadept.session` Module
diff --git a/docs/manual.md b/docs/manual.md
index 39ec09f7..7f2e2b13 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -7,7 +7,7 @@
3. [User Interface](#user-interface)
4. [Working with Files and Projects](#working-with-files-and-projects)
5. [Adept Editing](#adept-editing)
-6. [Compile, Run, and Build](#compile-run-and-build)
+6. [Compile, Run, Build, and Test](#compile-run-build-and-test)
7. [Modules](#modules)
8. [Themes](#themes)
9. [Scripting](#scripting)
@@ -1272,17 +1272,18 @@ outside that mode until the mode is unset (e.g. Vim-style modal editing). The
[keys documentation]: api.html#keys
--------------------------------------------------------------------------------
-### Compile, Run, and Build
+### Compile, Run, Build, and Test
--------------------------------------------------------------------------------
Textadept knows most of the commands that compile and/or run code in source
-files. It also knows some of the commands that build projects. Textadept
-recognizes many of the warning and error messages emitted by those commands and
-marks them as they occur in compile/run/build output. Double-clicking on a line
-with a warning or error jumps to its source.
+files. It also knows some of the commands that build projects, and you can tell
+the editor how to run your project's test suite. Textadept recognizes many of
+the warning and error messages emitted by those commands and marks them as they
+occur in compile/run/build/test output. Double-clicking on a line with a warning
+or error jumps to its source.
The following key bindings apply for compiling and running source files, and
-for building projects:
+for building projects and running tests:
* Compile the current file via `Ctrl+Shift+R` on Windows, Linux, and BSD, `⌘⇧R`
on macOS, and `M-^R` in the terminal version.
@@ -1295,9 +1296,11 @@ for building projects:
command and press `Enter` or click `OK`.
* Build the current project via `Ctrl+Shift+B` on Windows, Linux, and BSD, `⌘⇧B`
on macOS, and `M-^B` in the terminal version.
-* Stop the currently running compile, run, or build process via `Ctrl+Shift+X`
- on Windows, Linux, and BSD, `⌘⇧X` on macOS, and `M-^X` in the terminal
- version.
+* Run tests for the current project via `Ctrl+Shift+T` on Windows, Linux, and
+ BSD, `⌘⇧T` on macOS, and `M-^T` in the terminal version.
+* Stop the currently running compile, run, build, or test process via
+ `Ctrl+Shift+X` on Windows, Linux, and BSD, `⌘⇧X` on macOS, and `M-^X` in the
+ terminal version.
* Jump to the source of the next recognized warning or error via `Ctrl+Alt+E` on
Windows, Linux, and BSD, `^⌘E` on macOS, and `M-X` in the terminal version.
* Jump to the source of the previously recognized warning or error via
@@ -1308,25 +1311,26 @@ for building projects:
![Runtime Error](images/runerror.png)
-When you execute a compile, run, or build command, that command's output is
-printed to a temporary buffer in real-time. You can configure Textadept to print
-output in the background by setting [`textadept.run.run_in_background`][]. For
-example, in your *~/.textadept/init.lua*:
+When you execute a compile, run, build, or test command, that command's output
+is printed to a temporary buffer in real-time. You can configure Textadept to
+print output in the background by setting [`textadept.run.run_in_background`][].
+For example, in your *~/.textadept/init.lua*:
textadept.run.run_in_background = true
-You can change or add compile, run, and build commands by modifying the
-[`textadept.run.compile_commands`][], [`textadept.run.run_commands`][], and
-[`textadept.run.build_commands`][] tables, respectively. You can add Lua
-patterns that recognize warning and error output by modifying the
-[`textadept.run.error_patterns`][] table. For example, in your
-*~/.textadept/init.lua*:
+You can change or add compile, run, build, and test commands by modifying the
+[`textadept.run.compile_commands`][], [`textadept.run.run_commands`][],
+[`textadept.run.build_commands`][], and [`textadept.run.test_commands`][]
+tables, respectively. You can add Lua patterns that recognize warning and error
+output by modifying the [`textadept.run.error_patterns`][] table. For example,
+in your *~/.textadept/init.lua*:
textadept.run.compile_commands.foo = 'foo "%f"'
textadept.run.run_commands.foo = './"%e"'
textadept.run.error_patterns.foo = {'^(.-):(%d+): (.+)$'} -- bar.foo:1: oops
textadept.run.build_commands['/path/to/project'] = 'make -C src -j4'
+ textadept.run.test_commands['/path/to/project'] = 'lua tests.lua'
**Tip:** you can set compile and run commands on a per-filename basis, and these
commands can contain arguments so that you do not have to invoke
@@ -1336,6 +1340,7 @@ commands can contain arguments so that you do not have to invoke
[`textadept.run.compile_commands`]: api.html#textadept.run.compile_commands
[`textadept.run.run_commands`]: api.html#textadept.run.run_commands
[`textadept.run.build_commands`]: api.html#textadept.run.build_commands
+[`textadept.run.test_commands`]: api.html#textadept.run.test_commands
[`textadept.run.error_patterns`]: api.html#textadept.run.error_patterns
--------------------------------------------------------------------------------
diff --git a/modules/lua/ta_api b/modules/lua/ta_api
index edaf6115..85d9fb97 100644
--- a/modules/lua/ta_api
+++ b/modules/lua/ta_api
@@ -250,6 +250,7 @@ SUSPEND events.SUSPEND (string)\nEmitted when suspending Textadept. If any handl
TAB_CLICKED events.TAB_CLICKED (string)\nEmitted when the user clicks on a buffer tab.\nWhen connecting to this event, connect with an index of 1 if the handler\nneeds to run before Textadept switches between buffers.\nNote that Textadept always displays a context menu on right-click.\nArguments:\n\n* _`index`_: The numeric index of the clicked tab.\n* _`button`_: The mouse button number that was clicked, either `1` (left\n button), `2` (middle button), `3` (right button), `4` (wheel up), or `5`\n (wheel down).\n* _`shift`_: The "Shift" modifier key is held down.\n* _`ctrl`_: The "Control" modifier key is held down.\n* _`alt`_: The "Alt"/"Option" modifier key is held down.\n* _`cmd`_: The "Command" modifier key on macOS is held down.
TD_LONGARROW view.TD_LONGARROW (number, Read-only)\n
TD_STRIKEOUT view.TD_STRIKEOUT (number, Read-only)\n
+TEST_OUTPUT events.TEST_OUTPUT (string)\nEmitted when executing a project's shell command for running tests.\nBy default, output is printed to the message buffer. In order to override\nthis behavior, connect to the event with an index of `1` and return `true`.\nArguments:\n\n* `output`: A line of string output from the command.
TIME_FOREVER view.TIME_FOREVER (number, Read-only)\n
TYPE lexer.TYPE (string)\nThe token name for type tokens.
TYPEDEF textadept.editing.XPM_IMAGES.TYPEDEF (table)\nThe image number for type definitions.
@@ -804,7 +805,7 @@ rgba_image_height view.rgba_image_height (number)\nThe height of the RGBA image
rgba_image_scale view.rgba_image_scale (number)\nThe scale factor in percent of the RGBA image to be defined using\n`view.marker_define_rgba_image()`.\nThis is useful on macOS with a retina display where each display unit is 2\npixels: use a factor of `200` so that each image pixel is displayed using a\nscreen pixel. The default scale, `100`, will stretch each image pixel to\ncover 4 screen pixels on a retina display.
rgba_image_width view.rgba_image_width (number)\nThe width of the RGBA image to be defined using\n`view.marker_define_rgba_image()` and\n`view.register_rgba_image()`.
rotate_selection buffer.rotate_selection(buffer)\nDesignates the next additional selection to be the main selection.\n@param buffer A buffer.
-run textadept.run (module)\nCompile and run source code files with Textadept.\nLanguage modules may tweak the `compile_commands`,\n`run_commands`, and `error_patterns` tables for particular languages.\nThe user may tweak `build_commands` for particular projects.
+run textadept.run (module)\nCompile and run source code files with Textadept.\nLanguage modules may tweak the `compile_commands`,\n`run_commands`, and `error_patterns` tables for particular languages.\nThe user may tweak `build_commands` and `test_commands` for particular\nprojects.
run textadept.run.run(filename)\nRuns file *filename* or the current file using an appropriate shell command\nfrom the `run_commands` table.\nThe shell command is determined from the file's filename, extension, or\nlanguage in that order.\nEmits `RUN_OUTPUT` events.\n@param filename Optional path to the file to run. The default value is the\n current file's filename.\n@see run_commands\n@see _G.events
run ui.command_entry.run(f, keys, lang, height)\nOpens the command entry, subjecting it to any key bindings defined in table\n*keys*, highlighting text with lexer name *lang*, and displaying\n*height* number of lines at a time, and then when the `Enter` key is pressed,\ncloses the command entry and calls function *f* (if non-`nil`) with the\ncommand entry's text as an argument.\nBy default with no arguments given, opens a Lua command entry.\nThe command entry does not respond to Textadept's default key bindings, but\ninstead to the key bindings defined in *keys* and in\n`ui.command_entry.editing_keys`.\n@param f Optional function to call upon pressing `Enter` in the command\n entry, ending the mode. It should accept the command entry text as an\n argument.\n@param keys Optional table of key bindings to respond to. This is in\n addition to the basic editing and movement keys defined in\n `ui.command_entry.editing_keys`.\n `Esc` and `Enter` are automatically defined to cancel and finish the\n command entry, respectively.\n This parameter may be omitted completely.\n@param lang Optional string lexer name to use for command entry text. The\n default value is `'text'`.\n@param height Optional number of lines to display in the command entry. The\n default value is `1`.\n@usage ui.command_entry.run(ui.print)\n@see editing_keys
run_commands textadept.run.run_commands (table)\nMap of filenames, file extensions, and lexer names to their associated "run"\nshell command line strings or functions that return strings.\nCommand line strings may have the following macros:\n\n + `%f`: The file's name, including its extension.\n + `%e`: The file's name, excluding its extension.\n + `%d`: The file's directory path.\n + `%p`: The file's full path.\n\nFunctions may also return a working directory and process environment table\nto operate in. By default, the working directory is the current file's parent\ndirectory and the environment is Textadept's environment.
@@ -937,6 +938,8 @@ target_start buffer.target_start (number)\nThe position of the beginning of the
target_start_virtual_space buffer.target_start_virtual_space (number)\nThe position of the beginning of virtual space in the target range.\nThis is set to `1` when `buffer.target_start` or\n`buffer.target_end` is set, or when `buffer.set_target_range()` is\ncalled.
target_text buffer.target_text (string, Read-only)\nThe text in the target range.
target_whole_document buffer.target_whole_document(buffer)\nDefines the target range's beginning and end positions as the beginning and\nend positions of the document, respectively.\n@param buffer A buffer.
+test textadept.run.test(root_directory)\nRuns tests for the project whose root path is *root_directory* or the current\nproject using the shell command from the `test_commands` table.\nThe current project is determined by either the buffer's filename or the\ncurrent working directory.\nEmits `TEST_OUTPUT` events.\n@param root_directory The path to the project to run tests for. The default\n value is the current project.\n@see test_commands\n@see _G.events
+test_commands textadept.run.test_commands (table)\nMap of project root paths to their associated "test" shell command line\nstrings or functions that return such strings.\nFunctions may also return a working directory and process environment table\nto operate in. By default, the working directory is the project's root\ndirectory and the environment is Textadept's environment.
text_height view.text_height(view, line)\nReturns the pixel height of line number *line*.\n@param view A view.\n@param line The line number in *view* to get the pixel height of.\n@return number
text_length buffer.text_length (number, Read-only)\nThe number of bytes in the buffer.
text_range buffer.text_range(buffer, start_pos, end_pos)\nReturns the range of text between positions *start_pos* and *end_pos*.\n@param buffer A buffer.\n@param start_pos The start position of the range of text to get in *buffer*.\n@param end_pos The end position of the range of text to get in *buffer*.
diff --git a/modules/lua/ta_tags b/modules/lua/ta_tags
index 7e245f62..09f7071b 100644
--- a/modules/lua/ta_tags
+++ b/modules/lua/ta_tags
@@ -250,6 +250,7 @@ SUSPEND _HOME/core/events.lua /^module('events')]]$/;" F class:events
TAB_CLICKED _HOME/core/events.lua /^module('events')]]$/;" F class:events
TD_LONGARROW _HOME/core/.view.luadoc /^module('view')$/;" F class:view
TD_STRIKEOUT _HOME/core/.view.luadoc /^module('view')$/;" F class:view
+TEST_OUTPUT _HOME/modules/textadept/run.lua /^module('textadept.run')]]$/;" F class:events
TIME_FOREVER _HOME/core/.view.luadoc /^module('view')$/;" F class:view
TYPE _HOME/lexers/lexer.lua /^module('lexer')]=]$/;" F class:lexer
TYPEDEF _HOME/modules/textadept/editing.lua /^M.XPM_IMAGES = {not CURSES and '/* XPM */static char *class[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #001CD0","X c #008080","o c #0080E8","O c #00C0C0","+ c #24D0FC","@ c #00FFFF","# c #A4E8FC","$ c #C0FFFF","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or '*',not CURSES and '/* XPM */static char *namespace[] = {/* columns rows colors chars-per-pixel */"16 16 7 1 "," c #000000",". c #1D1D1D","X c #393939","o c #555555","O c #A8A8A8","+ c #AAAAAA","@ c None",/* pixels */"@@@@@@@@@@@@@@@@","@@@@+@@@@@@@@@@@","@@@.o@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@+.@@@@@@@+@@@@","@@+ @@@@@@@o.@@@","@@@ +@@@@@@+ @@@","@@@ +@@@@@@+ @@@","@@@.X@@@@@@@.+@@","@@@@+@@@@@@@ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@X.@@@","@@@@@@@@@@@+@@@@","@@@@@@@@@@@@@@@@"};' or '@',not CURSES and '/* XPM */static char *method[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOOOOO","OO X. OOOOOOOOO","OOOO OOOOOOOOOO"};' or '+',not CURSES and '/* XPM */static char *signal[] = {/* columns rows colors chars-per-pixel */"16 16 6 1 "," c #000000",". c #FF0000","X c #E0BC38","o c #F0DC5C","O c #FCFC80","+ c None",/* pixels */"++++++++++++++++","++++++++++++++++","++++++++++++++++","++++++++++ ++++","+++++++++ OO ++","++++++++ OOOOO +","+++++++ OOOOOX +","++++ + ooOOXX +","+++ OO oooXXX +","++ OOOOO ooXX ++","+ OOOOOX oX +++","+ ooOOXX + ++++","+ oooXXX +++++++","+ oooXX +++++..+","++ oX ++++++..+","++++ ++++++++++"};' or '~',not CURSES and '/* XPM */static char *slot[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOO ","OO X. OOOOOO O ","OOOO OOOOOOO "};' or '-',not CURSES and '/* XPM */static char *variable[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #8C748C","X c #9C94A4","o c #ACB4C0","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOO OOOOO","OOOOOOOO oo OOO","OOOOOOO ooooo OO","OOOOOO ooooo. OO","OOOOOO XXoo.. OO","OOOOOO XXX... OO","OOOOOO XXX.. OOO","OOOOOOO X. OOOO","OOOOOOOOO OOOOO","OOOOOOOOOOOOOOOO"};' or '.',not CURSES and '/* XPM */static char *struct[] = {/* columns rows colors chars-per-pixel */"16 16 14 1 "," c #000000",". c #008000","X c #00C000","o c #00FF00","O c #808000","+ c #C0C000","@ c #FFFF00","# c #008080","$ c #00C0C0","% c #00FFFF","& c #C0FFC0","* c #FFFFC0","= c #C0FFFF","- c None",/* pixels */"----- ---------","---- && -------","--- &&&oo ------","-- ooooo. ----","-- XXoo.. == --","-- XXX.. ===%% -","-- XXX. %%%%%# -","--- . $$%%## -","--- ** $$$### -","-- ***@@ $$## --","- @@@@@O $# ---","- ++@@OO - ----","- +++OOO -------","- +++OO --------","-- +O ---------","---- ----------"};' or '}',not CURSES and '/* XPM */static char *typedef[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #404040","X c #6D6D6D","o c #777777","O c #949494","+ c #ACACAC","@ c #BBBBBB","# c #DBDBDB","$ c #EEEEEE","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or ':',CLASS=1,NAMESPACE=2,METHOD=3,SIGNAL=4,SLOT=5,VARIABLE=6,STRUCT=7,TYPEDEF=8}$/;" F class:textadept.editing.XPM_IMAGES
@@ -939,6 +940,8 @@ target_start _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
target_start_virtual_space _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
target_text _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
target_whole_document _HOME/core/.buffer.luadoc /^function target_whole_document(buffer) end$/;" f class:buffer
+test _HOME/modules/textadept/run.lua /^function M.test(root_directory)$/;" f class:textadept.run
+test_commands _HOME/modules/textadept/run.lua /^M.test_commands = {}$/;" t class:textadept.run
text_height _HOME/core/.view.luadoc /^function text_height(view, line) end$/;" f class:view
text_length _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
text_range _HOME/core/.buffer.luadoc /^function text_range(buffer, start_pos, end_pos) end$/;" f class:buffer
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index c365191a..0e5e69d5 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -82,6 +82,7 @@ local M = {}
-- Ctrl+Shift+R |⌘⇧R |M-^R |Compile
-- Ctrl+Shift+A |⌘⇧A |None |Set Arguments...
-- Ctrl+Shift+B |⌘⇧B |M-^B |Build
+-- Ctrl+Shift+T |⌘⇧T |M-^T |Run tests
-- Ctrl+Shift+X |⌘⇧X |M-^X |Stop
-- Ctrl+Alt+E |^⌘E |M-X |Next Error
-- Ctrl+Alt+Shift+E|^⌘⇧E |M-S-X |Previous Error
@@ -221,7 +222,7 @@ module('textadept.keys')]]
-- Windows, Linux, and BSD key bindings.
--
-- Unassigned keys (~ denotes keys reserved by the operating system):
--- c: C H I Q T ~ V Y _ ) ] } +
+-- c: C H I Q ~ V Y _ ) ] } +
-- a: aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ_ ) ] } *+-/=\n\s
-- ca: aAbBcCdD F H jJkKlLmM N qQ t xXy zZ_"'()[]{}<>* / \n\s
--
@@ -234,7 +235,7 @@ module('textadept.keys')]]
-- macOS key bindings.
--
-- Unassigned keys (~ denotes keys reserved by the operating system):
--- m: C ~H I JkK ~M p ~ tT V yY _ ) ] } + ~~\n
+-- m: C ~H I JkK ~M p ~ t V yY _ ) ] } + ~~\n
-- c: cC D gG H J K L oO qQ xXyYzZ_ ) ] } * / \n
-- cm: aAbBcC~D F ~HiIjJkKlL~MnN p q~rRsStTuUvVwWxXyYzZ_"'()[]{}<>*+-/=\t\n
--
@@ -261,7 +262,7 @@ module('textadept.keys')]]
--
-- Unassigned keys (~ denotes keys reserved by the operating system):
-- c: g~~ l~ ~
--- cm: cd g~~ k ~ q t yz
+-- cm: cd g~~ k ~ q yz
-- m: e J qQ sS vVw yY _ +
-- Note: m[befhstv] may be used by Linux/BSD GUI terminals for menu access.
--
@@ -370,6 +371,7 @@ local bindings = {
[textadept.run.compile] = {'ctrl+R', 'cmd+R', 'ctrl+meta+r'},
[textadept.run.set_arguments] = {'ctrl+A', 'cmd+A', nil},
[textadept.run.build] = {'ctrl+B', 'cmd+B', 'ctrl+meta+b'},
+ [textadept.run.test] = {'ctrl+T', 'cmd+T', 'ctrl+meta+t'},
[textadept.run.stop] = {'ctrl+X', 'cmd+X', 'ctrl+meta+x'},
[m('Tools/Next Error')] = {'ctrl+alt+e', 'ctrl+cmd+e', 'meta+x'},
[m('Tools/Previous Error')] = {'ctrl+alt+E', 'ctrl+cmd+E', 'meta+X'},
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index 1ae2d909..b3ce1015 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -171,6 +171,7 @@ local default_menubar = {
{_L['Compile'], textadept.run.compile},
{_L['Set Arguments...'], textadept.run.set_arguments},
{_L['Build'], textadept.run.build},
+ {_L['Run tests'], textadept.run.test},
{_L['Stop'], textadept.run.stop},
{_L['Next Error'], function() textadept.run.goto_error(true) end},
{_L['Previous Error'], function() textadept.run.goto_error(false) end},
diff --git a/modules/textadept/run.lua b/modules/textadept/run.lua
index ba7526cf..f9f462f5 100644
--- a/modules/textadept/run.lua
+++ b/modules/textadept/run.lua
@@ -7,7 +7,8 @@ local M = {}
-- Compile and run source code files with Textadept.
-- [Language modules](#compile-and-run) may tweak the `compile_commands`,
-- `run_commands`, and `error_patterns` tables for particular languages.
--- The user may tweak `build_commands` for particular projects.
+-- The user may tweak `build_commands` and `test_commands` for particular
+-- projects.
-- @field run_in_background (bool)
-- Run shell commands silently in the background.
-- This only applies when the message buffer is open, though it does not have
@@ -43,6 +44,13 @@ local M = {}
-- Arguments:
--
-- * `output`: A line of string output from the command.
+-- @field _G.events.TEST_OUTPUT (string)
+-- Emitted when executing a project's shell command for running tests.
+-- By default, output is printed to the message buffer. In order to override
+-- this behavior, connect to the event with an index of `1` and return `true`.
+-- Arguments:
+--
+-- * `output`: A line of string output from the command.
module('textadept.run')]]
M.run_in_background = false
@@ -51,7 +59,9 @@ M.MARK_WARNING = _SCINTILLA.next_marker_number()
M.MARK_ERROR = _SCINTILLA.next_marker_number()
-- Events.
-local run_events = {'compile_output', 'run_output', 'build_output'}
+local run_events = {
+ 'compile_output', 'run_output', 'build_output', 'test_output'
+}
for _, v in ipairs(run_events) do events[v:upper()] = v end
-- Keep track of: the last process spawned in order to kill it if requested; the
@@ -92,10 +102,10 @@ local function scan_for_error(message, ext_or_lexer)
message:lower():find('warning') and not message:lower():find('error')
-- Compile and run commands specify the file extension or lexer name used
-- to determine the command, so the error patterns used are guaranteed to
- -- be correct. Build commands have no such context and instead iterate
- -- through all possible error patterns. Only consider the error/warning
- -- valid if the extracted filename's extension or lexer name matches the
- -- error pattern's extension or lexer name.
+ -- be correct. Build and test commands have no such context and instead
+ -- iterate through all possible error patterns. Only consider the
+ -- error/warning valid if the extracted filename's extension or lexer name
+ -- matches the error pattern's extension or lexer name.
if ext_or_lexer then return detail end
local ext = detail.filename:match('[^/\\.]+$')
local lexer_name = textadept.file_types.extensions[ext]
@@ -107,7 +117,7 @@ local function scan_for_error(message, ext_or_lexer)
return nil
end
--- Prints an output line from a compile, run, or build shell command.
+-- Prints an output line from a compile, run, build, or test shell command.
-- Assume output is UTF-8 unless there's a recognized warning or error message.
-- In that case assume it is encoded in _CHARSET and mark it.
-- All stdout and stderr from the command is printed silently.
@@ -129,8 +139,8 @@ local function print_line(line, ext_or_lexer)
end
local output_buffer
--- Prints the output from a compile, run, or build shell command as a series of
--- lines, performing buffering as needed.
+-- Prints the output from a compile, run, build, or test shell command as a
+-- series of lines, performing buffering as needed.
-- @param output The output to print, or `nil` to flush any buffered output.
-- @param ext_or_lexer Optional file extension or lexer name associated with the
-- executed command. This is used for better error detection in compile and
@@ -369,6 +379,38 @@ end
events.connect(events.BUILD_OUTPUT, print_output)
---
+-- Map of project root paths to their associated "test" shell command line
+-- strings or functions that return such strings.
+-- Functions may also return a working directory and process environment table
+-- to operate in. By default, the working directory is the project's root
+-- directory and the environment is Textadept's environment.
+-- @class table
+-- @name test_commands
+M.test_commands = {}
+
+---
+-- Runs tests for the project whose root path is *root_directory* or the current
+-- project using the shell command from the `test_commands` table.
+-- The current project is determined by either the buffer's filename or the
+-- current working directory.
+-- Emits `TEST_OUTPUT` events.
+-- @param root_directory The path to the project to run tests for. The default
+-- value is the current project.
+-- @see test_commands
+-- @see _G.events
+-- @name test
+function M.test(root_directory)
+ if not assert_type(root_directory, 'string/nil', 1) then
+ root_directory = io.get_project_root()
+ if not root_directory then return end
+ end
+ for i = 1, #_BUFFERS do _BUFFERS[i]:annotation_clear_all() end
+ run_command(
+ M.test_commands[root_directory], root_directory, events.TEST_OUTPUT)
+end
+events.connect(events.TEST_OUTPUT, print_output)
+
+---
-- Stops the currently running process, if any.
-- @name stop
function M.stop() if proc then proc:kill() end end
diff --git a/test/modules/textadept/run/test.lua b/test/modules/textadept/run/test.lua
new file mode 100644
index 00000000..7e275ac2
--- /dev/null
+++ b/test/modules/textadept/run/test.lua
@@ -0,0 +1 @@
+print('test.lua:1: assertion failed!')
diff --git a/test/test.lua b/test/test.lua
index 5a0fae05..8503615d 100644
--- a/test/test.lua
+++ b/test/test.lua
@@ -3120,6 +3120,18 @@ function test_run_build()
-- TODO: project whose makefile is autodetected.
end
+function test_run_test()
+ textadept.run.test_commands[_HOME] = function()
+ return 'lua modules/textadept/run/test.lua', _HOME .. '/test/' -- intentional trailing '/'
+ end
+ textadept.run.test(_HOME)
+ if #_VIEWS > 1 then view:unsplit() end
+ ui.update() -- process output
+ assert(buffer:get_text():find('test%.lua'), 'did not run test command')
+ assert(buffer:get_text():find('assertion failed!'), 'assertion failure not detected')
+ buffer:close()
+end
+
function test_run_goto_internal_lua_error()
xpcall(error, function(message) events.emit(events.ERROR, debug.traceback(message)) end, 'internal error', 2)
if #_VIEWS > 1 then view:unsplit() end