├── .codecov.yml ├── .github ├── DISCUSSION_TEMPLATE │ └── packages.yaml ├── ISSUE_TEMPLATE │ ├── autocomplete-request.md │ ├── bug-report.md │ ├── feature-request.md │ └── support-request.md └── workflows │ ├── archlinux-aur-package.yaml │ ├── aur │ ├── PKGBUILD │ └── SRCINFO │ ├── clean-build.yaml │ ├── code-coverage.yaml │ ├── deploy-dev-docs.yaml │ ├── deploy-docs.yaml │ ├── murex-downloads.yaml │ └── murex-tests.yaml ├── .gitignore ├── CONTRIBUTING.md ├── DOWNLOAD.md ├── INSTALL.md ├── LICENSE ├── README.md ├── app ├── app.go ├── app_test.go ├── update-version.mx └── whatsnew │ └── whatsnew.go ├── behavioural ├── alias_len.mx ├── cast.mx ├── config_strict-vars.mx ├── event_cc_panic.mx ├── exec_data_types.mx ├── exec_data_types.mx.resource ├── exec_data_types.sh.resource ├── export_crash.mx ├── expressions.mx ├── murex_flags.mx ├── onSignalReceived.mx ├── quiet_flag.mx ├── return.mx ├── try_control.mx ├── try_scopes.mx └── tryerr_scopes.mx ├── benchmarks_test.go ├── builtins ├── core.go ├── core │ ├── arraytools │ │ ├── 2darray.go │ │ ├── 2darray_doc.yaml │ │ ├── 2darray_test.go │ │ ├── addheading.go │ │ ├── addheading_doc.yaml │ │ ├── addheading_test.go │ │ ├── godoc.go │ │ ├── map.go │ │ ├── map_doc.yaml │ │ └── map_test.go │ ├── autocomplete │ │ ├── autocomplete.go │ │ ├── autocomplete_doc.inc.md │ │ ├── autocomplete_doc.yaml │ │ ├── autocomplete_test.go │ │ └── mxjson_bug_test.go │ ├── config │ │ ├── cmd.go │ │ ├── config_doc.inc.md │ │ ├── config_doc.yaml │ │ ├── config_test.go │ │ ├── define.go │ │ ├── dynamic.go │ │ ├── dynamic_test.go │ │ ├── eval.go │ │ └── eval_test.go │ ├── datatools │ │ ├── README.md │ │ ├── alter.go │ │ ├── alter_doc.yaml │ │ ├── alter_op_test.go │ │ ├── alter_test.go │ │ ├── count.go │ │ ├── count_doc.yaml │ │ ├── count_test.go │ │ ├── godoc.go │ │ ├── len_test.go │ │ ├── structkeys.go │ │ ├── structkeys_doc.yaml │ │ └── structkeys_test.go │ ├── element │ │ ├── element.go │ │ ├── element_doc.yaml │ │ └── element_test.go │ ├── escape │ │ ├── README.md │ │ ├── escape.go │ │ ├── escape_doc.yaml │ │ ├── escape_test.go │ │ └── godoc.go │ ├── expressions │ │ ├── expressions.go │ │ ├── expressions_doc.yaml │ │ └── expressions_test.go │ ├── httpclient │ │ ├── README.md │ │ ├── client.go │ │ ├── get.go │ │ ├── get_doc.yaml │ │ ├── get_test.go │ │ ├── getfile.go │ │ ├── getfile_test.go │ │ ├── godoc.go │ │ ├── init.go │ │ ├── post.go │ │ ├── post_doc.yaml │ │ ├── post_test.go │ │ ├── server_test.go │ │ └── structs.go │ ├── index │ │ ├── index.go │ │ ├── index_doc.yaml │ │ └── index_test.go │ ├── io │ │ ├── DUMMYFILE_test.md │ │ ├── README.md │ │ ├── echo.go │ │ ├── echo_doc.yaml │ │ ├── echo_test.go │ │ ├── f.go │ │ ├── f_doc.yaml │ │ ├── f_enum.go │ │ ├── f_plan9.go │ │ ├── f_test.go │ │ ├── f_types.go │ │ ├── f_unix.go │ │ ├── f_windows.go │ │ ├── fflagst_string.go │ │ ├── g.go │ │ ├── g_doc.yaml │ │ ├── g_test.go │ │ ├── lockfile.go │ │ ├── lockfile_doc.yaml │ │ ├── pt.go │ │ ├── pt_doc.yaml │ │ ├── pt_test.go │ │ ├── read.go │ │ ├── read_doc.yaml │ │ ├── read_test.go │ │ ├── rx.go │ │ ├── rx_doc.yaml │ │ ├── rx_test.go │ │ ├── tmp.go │ │ ├── tmp_doc.yaml │ │ ├── tmp_test.go │ │ ├── write.go │ │ ├── write_doc.yaml │ │ ├── write_test.go │ │ └── write_unix_test.go │ ├── lists │ │ ├── append.go │ │ ├── append_doc.yaml │ │ ├── append_test.go │ │ ├── case.go │ │ ├── case_doc.yaml │ │ ├── case_test.go │ │ ├── jsplit.go │ │ ├── jsplit_doc.yaml │ │ ├── jsplit_test.go │ │ ├── match.go │ │ ├── match_doc.yaml │ │ ├── match_test.go │ │ ├── mjoin.go │ │ ├── mjoin_doc.yaml │ │ ├── mjoin_test.go │ │ ├── msort.go │ │ ├── msort_doc.yaml │ │ ├── msort_test.go │ │ ├── mtac.go │ │ ├── mtac_doc.yaml │ │ ├── mtac_test.go │ │ ├── prepend_test.go │ │ ├── push_pop.go │ │ ├── push_pop_doc.yaml │ │ ├── push_pop_test.go │ │ ├── regexp.go │ │ ├── regexp_doc.yaml │ │ ├── regexp_functions.go │ │ ├── regexp_params.go │ │ └── regexp_test.go │ ├── management │ │ ├── README.md │ │ ├── debug.go │ │ ├── debug_doc.yaml │ │ ├── fexec.go │ │ ├── fexec_doc.yaml │ │ ├── fexec_test.go │ │ ├── functions.go │ │ ├── functions_doc.yaml │ │ ├── functions_test.go │ │ ├── godoc.go │ │ ├── history.go │ │ ├── history_doc.yaml │ │ ├── shell.go │ │ ├── shell_doc.yaml │ │ ├── shell_test.go │ │ ├── source.go │ │ ├── source_doc.yaml │ │ ├── source_test.go │ │ ├── source_test.mx │ │ ├── type.go │ │ ├── type_doc.yaml │ │ ├── version.go │ │ ├── version_doc.yaml │ │ ├── version_test.go │ │ ├── which.go │ │ └── which_doc.yaml │ ├── mkarray │ │ ├── README.md │ │ ├── array_doc.yaml │ │ ├── array_num.go │ │ ├── array_str.go │ │ ├── array_test.go │ │ ├── case.go │ │ ├── case_test.go │ │ ├── consts.go │ │ ├── consts_test.go │ │ ├── date.go │ │ ├── godoc.go │ │ ├── mkarray.go │ │ ├── range.go │ │ ├── range_test.go │ │ └── ranges_doc.yaml │ ├── modules │ │ ├── cmd-get.go │ │ ├── cmd-git.go │ │ ├── cmd-import.go │ │ ├── cmd-list.go │ │ ├── cmd-new.go │ │ ├── cmd-new.mx │ │ ├── cmd-remove.go │ │ ├── cmd-status.go │ │ ├── cmd.go │ │ ├── disable.go │ │ ├── enable.go │ │ ├── git.go │ │ ├── git_test.go │ │ ├── modules_test.go │ │ ├── murex-package_doc.yaml │ │ └── package.go │ ├── open │ │ ├── agents.go │ │ ├── http.go │ │ ├── http_test.go │ │ ├── open.go │ │ ├── open_doc.yaml │ │ ├── openagent.go │ │ └── system.go │ ├── openimage │ │ ├── README.md │ │ ├── godoc.go │ │ ├── open-image.go │ │ ├── open-image_doc.yaml │ │ └── open-image_test.go │ ├── pipe │ │ ├── namedpipe.go │ │ ├── namedpipe_doc.yaml │ │ ├── namedpipe_test.go │ │ ├── pipe.go │ │ ├── pipe_doc.yaml │ │ └── pipe_test.go │ ├── pretty │ │ ├── godoc.go │ │ ├── pretty.go │ │ ├── pretty_doc.yaml │ │ └── pretty_test.go │ ├── processes │ │ ├── README.md │ │ ├── bgfg.go │ │ ├── bgfg_doc.yaml │ │ ├── bgfg_js.go │ │ ├── bgfg_plan9.go │ │ ├── bgfg_test.go │ │ ├── bgfg_unix.go │ │ ├── bgfg_windows.go │ │ ├── fid-list.go │ │ ├── fid-list_doc.yaml │ │ ├── godoc.go │ │ ├── jobs.go │ │ ├── kill.go │ │ └── kill_doc.yaml │ ├── random │ │ ├── rand.go │ │ ├── rand_doc.yaml │ │ └── rand_test.go │ ├── ranges │ │ ├── buffer.go │ │ ├── index.go │ │ ├── index_test.go │ │ ├── number.go │ │ ├── number_test.go │ │ ├── ranges.go │ │ ├── ranges_doc.yaml │ │ ├── read_array.go │ │ ├── regexp.go │ │ ├── regexp_test.go │ │ ├── string.go │ │ └── string_test.go │ ├── runtime │ │ ├── godoc.go │ │ ├── runtime.go │ │ ├── runtime_doc.yaml │ │ └── runtime_test.go │ ├── structs │ │ ├── README.md │ │ ├── alias_test.go │ │ ├── and_test.go │ │ ├── andor.go │ │ ├── andor_doc.yaml │ │ ├── break.go │ │ ├── break_doc.yaml │ │ ├── break_test.go │ │ ├── for.go │ │ ├── for_doc.yaml │ │ ├── for_test.go │ │ ├── foreach.go │ │ ├── foreach_doc.yaml │ │ ├── foreach_test.go │ │ ├── formap.go │ │ ├── formap_doc.yaml │ │ ├── function.go │ │ ├── function_doc.yaml │ │ ├── function_test.go │ │ ├── godoc.go │ │ ├── if.go │ │ ├── if_doc.yaml │ │ ├── if_test.go │ │ ├── or_test.go │ │ ├── switch.go │ │ ├── switch_doc.yaml │ │ ├── switch_test.go │ │ ├── try.go │ │ ├── try_doc.yaml │ │ ├── try_test.go │ │ ├── tryerr_doc.yaml │ │ ├── while.go │ │ ├── while_doc.yaml │ │ └── while_test.go │ ├── system │ │ ├── system.go │ │ ├── system_doc.yaml │ │ ├── system_test.go │ │ ├── system_unix_test.go │ │ └── system_windows_test.go │ ├── tabulate │ │ ├── tabulate.go │ │ ├── tabulate_dc_test.go │ │ ├── tabulate_doc.yaml │ │ ├── tabulate_git_test.go │ │ ├── tabulate_make_test.go │ │ ├── tabulate_sd_test.go │ │ ├── tabulate_test.go │ │ ├── tabulate_tf_test.go │ │ ├── writer.go │ │ └── writer_map.go │ ├── test │ │ ├── define.go │ │ ├── run.go │ │ ├── state.go │ │ ├── test.go │ │ ├── test_doc.yaml │ │ └── unit.go │ ├── time │ │ ├── README.md │ │ ├── datetime.go │ │ ├── datetime_doc.yaml │ │ ├── godoc.go │ │ ├── time.go │ │ ├── time_doc.yaml │ │ └── time_test.go │ ├── typemgmt │ │ ├── README.md │ │ ├── export_test.go │ │ ├── format.go │ │ ├── format_doc.yaml │ │ ├── gettype.go │ │ ├── gettype_doc.yaml │ │ ├── gettype_test.go │ │ ├── global_test.go │ │ ├── godoc.go │ │ ├── isnull.go │ │ ├── isnull_doc.yaml │ │ ├── isnull_test.go │ │ ├── let.go │ │ ├── let_test.go │ │ ├── math.go │ │ ├── math_doc.yaml │ │ ├── parameters_test.go │ │ ├── round.go │ │ ├── round_doc.yaml │ │ ├── round_test.go │ │ ├── scoping_test.go │ │ ├── set_test.go │ │ ├── types.go │ │ ├── types_doc.yaml │ │ ├── variables.go │ │ ├── variables_doc.yaml │ │ └── variables_test.go │ └── vis │ │ ├── godoc.go │ │ └── vis.go ├── docs │ ├── docs.go │ ├── docs_doc.yaml │ ├── docs_test.go │ └── summaries.go ├── events │ ├── README.md │ ├── cmd.go │ ├── events_doc.yaml │ ├── godoc.go │ ├── handler.go │ ├── keys.go │ ├── onCommandCompletion │ │ ├── commandcompletion.go │ │ └── oncommandcompletion_doc.yaml │ ├── onFileSystemChange │ │ ├── filesystem_js.go │ │ ├── filesystem_plan9.go │ │ ├── filesystem_test.go │ │ ├── filesystem_unix.go │ │ ├── filesystem_windows.go │ │ └── onfilesystemchange_doc.yaml │ ├── onKeyPress │ │ ├── actions.mx │ │ ├── actions_generated.go │ │ ├── keycode.go │ │ ├── keycodes_doc.yaml │ │ ├── keypress.go │ │ ├── onkeypress-event-return.inc.md │ │ ├── onkeypress-payload.inc.md │ │ ├── onkeypress_doc.yaml │ │ └── return.go │ ├── onPreview │ │ ├── cache.go │ │ ├── onpreview.go │ │ ├── onpreview_doc.yaml │ │ ├── onpreview_release.go │ │ ├── onpreview_trace.go │ │ ├── preview_interrupts.go │ │ ├── previewops │ │ │ └── interrupt_operations.go │ │ └── return.go │ ├── onPrompt │ │ ├── onprompt.go │ │ ├── onprompt_doc.yaml │ │ ├── onprompt_release.go │ │ ├── onprompt_trace.go │ │ ├── prompt_interrupts.go │ │ └── promptops │ │ │ └── interrupt_operations.go │ ├── onSecondsElapsed │ │ ├── onsecondselapsed_doc.yaml │ │ └── timer.go │ └── onSignalReceived │ │ ├── interrupts.go │ │ ├── interrupts_aix.go │ │ ├── interrupts_darwin.go │ │ ├── interrupts_dragonfly.go │ │ ├── interrupts_freebsd.go │ │ ├── interrupts_js.go │ │ ├── interrupts_linux.go │ │ ├── interrupts_netbsd.go │ │ ├── interrupts_openbsd.go │ │ ├── interrupts_plan9.go │ │ ├── interrupts_solaris.go │ │ ├── interrupts_windows.go │ │ ├── onSignalReceived.go │ │ ├── onSignalReceived_doc.yaml │ │ ├── register.go │ │ ├── signal.go │ │ ├── signal_detail.inc.md │ │ ├── signal_doc.yaml │ │ ├── signal_js.go │ │ ├── signal_plan9.go │ │ ├── signal_posix.go │ │ └── signals.inc.md ├── godoc.go ├── optional │ ├── dummy.go │ ├── encoders │ │ ├── README.md │ │ ├── base64.go │ │ ├── base64_doc.yaml │ │ ├── bz2.go │ │ ├── bz2_doc.yaml │ │ ├── godoc.go │ │ ├── gz.go │ │ └── gz_doc.yaml │ ├── optional-barcode.go │ ├── optional-encoders.go │ ├── optional-printf.go │ ├── optional-select.go │ ├── optional-time.go │ ├── pipe-mail.go │ ├── pipe-net.go │ ├── printf │ │ └── printf.go │ ├── qr │ │ ├── README.md │ │ ├── godoc.go │ │ ├── init.go │ │ └── qr_doc.yaml │ ├── select │ │ ├── autocomplete.go │ │ ├── godoc.go │ │ ├── lib_c.go │ │ ├── lib_go.go │ │ ├── select.go │ │ ├── select_doc.yaml │ │ ├── select_test.go │ │ ├── sqlite3.go │ │ ├── tables.go │ │ └── utils_test.go │ ├── standard-opts.txt │ ├── time │ │ ├── README.md │ │ ├── godoc.go │ │ ├── sleep.go │ │ └── sleep_doc.yaml │ ├── type-hcl.go │ ├── type-sexp.go │ └── wasm-opts.txt ├── pipes │ ├── file │ │ ├── file.go │ │ ├── file_test.go │ │ ├── neg_panic.go │ │ ├── neg_panic_test.go │ │ ├── struct.go │ │ └── write.go │ ├── mail │ │ ├── config.go │ │ ├── godoc.go │ │ ├── smtp.go │ │ ├── stdio.go │ │ ├── utils.go │ │ └── utils_test.go │ ├── net │ │ ├── neg_panic.go │ │ ├── neg_panic_test.go │ │ ├── net.go │ │ ├── new.go │ │ ├── read.go │ │ └── write.go │ ├── null │ │ ├── godoc.go │ │ ├── null.go │ │ └── null_test.go │ ├── psuedotty │ │ ├── neg_panic.go │ │ ├── neg_panic_test.go │ │ ├── pty_fallback.go │ │ ├── pty_unix.go │ │ └── teepty.go │ ├── streams │ │ ├── define.go │ │ ├── godoc.go │ │ ├── neg_panic.go │ │ ├── neg_panic_test.go │ │ ├── read.go │ │ ├── readcloser.go │ │ ├── reader.go │ │ ├── stdtest.go │ │ ├── tee.go │ │ ├── utils.go │ │ ├── utils_test.go │ │ └── write.go │ └── term │ │ ├── err.go │ │ ├── err_js.go │ │ ├── godoc.go │ │ ├── in.go │ │ ├── out.go │ │ ├── out_js.go │ │ ├── red.go │ │ ├── red_js.go │ │ ├── term.go │ │ ├── term_js.go │ │ ├── utils.go │ │ └── utils_test.go └── types │ ├── apachelogs │ ├── README.md │ ├── apachelogs.go │ ├── apachelogs_doc.yaml │ ├── array.go │ ├── godoc.go │ ├── index.go │ ├── map.go │ └── marshal.go │ ├── boolean │ ├── boolean_doc.yaml │ ├── godoc.go │ ├── init.go │ └── marshal.go │ ├── columns │ ├── columns.go │ ├── godoc.go │ └── marshal.go │ ├── csv-bad │ ├── README.md │ ├── csv.go │ ├── godoc.go │ ├── index.go │ ├── init.go │ ├── map.go │ ├── map_test.go │ └── marshal.go │ ├── csv │ ├── README.md │ ├── csv.go │ ├── csv_doc.yaml │ ├── godoc.go │ ├── index.go │ ├── map.go │ ├── map_test.go │ ├── marshal.go │ └── marshal_test.go │ ├── example │ ├── marshal.go │ ├── marshal_test.go │ ├── unmarshal.go │ └── unmarshal_test.go │ ├── generic │ ├── array_read.go │ ├── array_write.go │ ├── generic.go │ ├── generic_doc.yaml │ ├── generic_test.go │ ├── godoc.go │ ├── index.go │ ├── index_test.go │ ├── map.go │ └── marshal.go │ ├── hcl │ ├── README.md │ ├── array.go │ ├── godoc.go │ ├── hcl.go │ └── hcl_doc.yaml │ ├── json │ ├── array_read.go │ ├── array_read_type.go │ ├── array_write.go │ ├── godoc.go │ ├── index.go │ ├── json.go │ ├── json_doc.yaml │ ├── json_test.go │ ├── map.go │ ├── marshal.go │ └── mxjson_doc.yaml │ ├── jsonconcat │ ├── array.go │ ├── godoc.go │ ├── index.go │ ├── json.go │ ├── jsonconcat.go │ ├── jsonconcat_doc.yaml │ ├── jsonlines.go │ ├── map.go │ ├── marshal.go │ ├── object_test.go │ ├── parser.go │ ├── parser_fuzz_test.go │ ├── table_test.go │ └── unmarshal.go │ ├── jsonlines │ ├── array.go │ ├── enclosure.go │ ├── enclosure_test.go │ ├── godoc.go │ ├── index.go │ ├── jsonlines.go │ ├── jsonlines_doc.yaml │ ├── map.go │ ├── marshal.go │ ├── object_test.go │ ├── table_test.go │ └── unmarshal.go │ ├── null │ ├── array.go │ ├── init.go │ ├── marshal.go │ └── null_test.go │ ├── numeric │ ├── godoc.go │ ├── init.go │ ├── marshal.go │ └── numeric_doc.yaml │ ├── paths │ ├── array_read.go │ ├── array_read_type.go │ ├── array_write.go │ ├── godoc.go │ ├── index.go │ ├── init.go │ ├── marshal.go │ ├── mxi.go │ ├── path_doc.yaml │ ├── paths_doc.yaml │ ├── separator_unix.go │ └── separator_windows.go │ ├── querystring │ ├── array.go │ ├── godoc.go │ ├── index.go │ ├── map.go │ ├── marshal.go │ └── querystring.go │ ├── sexp │ ├── README.md │ ├── array_read.go │ ├── array_write.go │ ├── godoc.go │ ├── map.go │ └── sexp.go │ ├── string │ ├── array_read.go │ ├── array_read_type.go │ ├── array_write.go │ ├── godoc.go │ ├── index.go │ ├── index_test.go │ ├── init.go │ ├── map.go │ ├── marshal.go │ └── string_doc.yaml │ ├── toml │ ├── README.md │ ├── array_read.go │ ├── godoc.go │ ├── map.go │ ├── toml.go │ ├── toml_doc.yaml │ └── toml_test.go │ └── yaml │ ├── README.md │ ├── array_write.go │ ├── godoc.go │ ├── yaml.go │ ├── yaml_doc.yaml │ └── yaml_test.go ├── compatibility.md ├── config ├── config.go ├── config_test.go ├── defaults │ ├── config.go │ ├── config_test.go │ ├── godoc.go │ ├── profile.go │ ├── profile_any.go │ ├── profile_any.mx │ ├── profile_darwin.go │ ├── profile_darwin.mx │ ├── profile_dragonfly.go │ ├── profile_dragonfly.mx │ ├── profile_freebsd.go │ ├── profile_freebsd.mx │ ├── profile_linux.go │ ├── profile_linux.mx │ ├── profile_netbsd.go │ ├── profile_netbsd.mx │ ├── profile_openbsd.go │ ├── profile_openbsd.mx │ ├── profile_plan9.go │ ├── profile_plan9.mx │ ├── profile_posix.go │ ├── profile_posix.mx │ ├── profile_preload.go │ ├── profile_preload.mx │ ├── profile_solaris.go │ ├── profile_solaris.mx │ ├── profile_windows.go │ └── profile_windows.mx ├── godoc.go └── profile │ ├── godoc.go │ ├── json.go │ ├── module.go │ ├── module_test.go │ ├── module_test.mx │ ├── packages.go │ ├── paths.go │ ├── paths_test.go │ └── profile.go ├── debug ├── badmutex.go ├── badmutex_test.go ├── debug.go ├── godoc.go └── vmutex.go ├── defaults_test.go ├── docs.go ├── docs ├── apis │ ├── Marshal.md │ ├── README.md │ ├── ReadArray.md │ ├── ReadArrayWithType.md │ ├── ReadIndex.md │ ├── ReadMap.md │ ├── ReadNotIndex.md │ ├── Unmarshal.md │ ├── WriteArray.md │ ├── lang.ArrayTemplate.md │ ├── lang.ArrayWithTypeTemplate.md │ ├── lang.IndexTemplateObject.md │ ├── lang.IndexTemplateTable.md │ ├── lang.MarshalData.md │ └── lang.UnmarshalData.md ├── blog │ ├── README.md │ ├── reading_lists.md │ └── split_personalities.md ├── changelog │ ├── README.md │ ├── v2.0.md │ ├── v2.1.md │ ├── v2.10.md │ ├── v2.11.md │ ├── v2.2.md │ ├── v2.3.md │ ├── v2.4.md │ ├── v2.5.md │ ├── v2.6.md │ ├── v2.7.md │ ├── v2.8.md │ ├── v2.9.md │ ├── v3.0.md │ ├── v3.1.md │ ├── v4.0.md │ ├── v4.1.md │ ├── v4.2.md │ ├── v4.3.md │ ├── v4.4.md │ ├── v5.0.md │ ├── v5.1.md │ ├── v5.2.md │ ├── v5.3.md │ ├── v6.0.md │ ├── v6.1.md │ ├── v6.2.md │ ├── v6.3.md │ └── v6.4.md ├── commands │ ├── 2darray.md │ ├── README.md │ ├── a.md │ ├── addheading.md │ ├── alias.md │ ├── alter.md │ ├── and.md │ ├── append.md │ ├── args.md │ ├── autocomplete.md │ ├── bexists.md │ ├── bg.md │ ├── break.md │ ├── cast.md │ ├── catch.md │ ├── cd.md │ ├── config.md │ ├── continue.md │ ├── count.md │ ├── cpuarch.md │ ├── cpucount.md │ ├── datetime.md │ ├── debug.md │ ├── devnull.md │ ├── die.md │ ├── err.md │ ├── escape.md │ ├── esccli.md │ ├── eschtml.md │ ├── escurl.md │ ├── event.md │ ├── exec.md │ ├── exit.md │ ├── exitnum.md │ ├── export.md │ ├── expr.md │ ├── f.md │ ├── false.md │ ├── fexec.md │ ├── fg.md │ ├── fid-kill.md │ ├── fid-killall.md │ ├── fid-list.md │ ├── for.md │ ├── foreach.md │ ├── formap.md │ ├── format.md │ ├── function.md │ ├── g.md │ ├── get-type.md │ ├── get.md │ ├── getfile.md │ ├── global.md │ ├── history.md │ ├── if.md │ ├── is-null.md │ ├── ja.md │ ├── jsplit.md │ ├── key-code.md │ ├── left.md │ ├── let.md │ ├── list.case.md │ ├── lockfile.md │ ├── man-get-flags.md │ ├── man-summary.md │ ├── map.md │ ├── match.md │ ├── method.md │ ├── mjoin.md │ ├── msort.md │ ├── mtac.md │ ├── murex-docs.md │ ├── murex-package.md │ ├── murex-parser.md │ ├── murex-update-exe-list.md │ ├── not-func.md │ ├── open-image.md │ ├── open.md │ ├── openagent.md │ ├── or.md │ ├── os.md │ ├── out.md │ ├── pipe.md │ ├── post.md │ ├── prefix.md │ ├── prepend.md │ ├── pretty.md │ ├── private.md │ ├── pt.md │ ├── rand.md │ ├── read.md │ ├── regexp.md │ ├── return.md │ ├── right.md │ ├── round.md │ ├── runmode.md │ ├── runtime.md │ ├── rx.md │ ├── set.md │ ├── signal.md │ ├── source.md │ ├── struct-keys.md │ ├── suffix.md │ ├── summary.md │ ├── switch.md │ ├── ta.md │ ├── tabulate.md │ ├── test.md │ ├── time.md │ ├── tmp.md │ ├── tout.md │ ├── tread.md │ ├── true.md │ ├── try.md │ ├── tryerr.md │ ├── trypipe.md │ ├── trypipeerr.md │ ├── type.md │ ├── unsafe.md │ ├── version.md │ ├── which.md │ └── while.md ├── events │ ├── README.md │ ├── oncommandcompletion.md │ ├── onfilesystemchange.md │ ├── onkeypress.md │ ├── onpreview.md │ ├── onprompt.md │ ├── onsecondselapsed.md │ └── onsignalreceived.md ├── integrations │ ├── README.md │ ├── chatgpt.md │ ├── cheatsh.md │ ├── direnv.md │ ├── iterm2.md │ ├── kitty.md │ ├── make.md │ ├── man-pages.md │ ├── spellcheck.md │ ├── terminology.md │ └── yarn.md ├── mkarray │ ├── character.md │ ├── date.md │ ├── decimal.md │ ├── non-decimal.md │ └── special.md ├── optional │ ├── README.md │ ├── base64.md │ ├── bz2.md │ ├── gz.md │ ├── qr.md │ ├── select.md │ └── sleep.md ├── parser │ ├── README.md │ ├── add-with.md │ ├── addition.md │ ├── array.md │ ├── assign-or-merge.md │ ├── brace-quote-func.md │ ├── brace-quote.md │ ├── c-style-fun.md │ ├── create-array.md │ ├── create-object.md │ ├── curly-brace.md │ ├── divide-by.md │ ├── division.md │ ├── double-quote.md │ ├── element.md │ ├── elvis.md │ ├── equ.md │ ├── expr-inlined.md │ ├── file-append.md │ ├── file-truncate.md │ ├── item-index.md │ ├── lambda.md │ ├── logical-and.md │ ├── logical-or.md │ ├── multiplication.md │ ├── multiply-by.md │ ├── namedpipe.md │ ├── null-coalescing.md │ ├── pipe-arrow.md │ ├── pipe-err.md │ ├── pipe-generic.md │ ├── pipe-posix.md │ ├── range.md │ ├── scalar.md │ ├── single-quote.md │ ├── stdin.md │ ├── subtract-by.md │ ├── subtraction.md │ └── tilde.md ├── supported-platforms.md ├── tour.md ├── types │ ├── README.md │ ├── bool.md │ ├── commonlog.md │ ├── csv.md │ ├── float.md │ ├── generic.md │ ├── hcl.md │ ├── int.md │ ├── json.md │ ├── jsonc.md │ ├── jsonl.md │ ├── mxjson.md │ ├── num.md │ ├── path.md │ ├── paths.md │ ├── str.md │ ├── toml.md │ └── yaml.md ├── user-guide │ ├── README.md │ ├── ansi.md │ ├── bang-prefix.md │ ├── code-block.md │ ├── fileref.md │ ├── hint-text.md │ ├── integrations.md │ ├── interactive-shell.md │ ├── job-control.md │ ├── modules.md │ ├── murex-arrays.md │ ├── namedpipes.md │ ├── operators-and-tokens.md │ ├── pipeline.md │ ├── profile.md │ ├── reserved-vars.md │ ├── rosetta-stone.md │ ├── schedulers.md │ ├── scoping.md │ ├── strict-types.md │ └── terminal-keys.md └── variables │ ├── README.md │ ├── argv.md │ ├── columns.md │ ├── event_return.md │ ├── home.md │ ├── hostname.md │ ├── lines.md │ ├── logname.md │ ├── meta-values.md │ ├── murex_argv.md │ ├── murex_exe.md │ ├── numeric.md │ ├── oldpwd.md │ ├── params.md │ ├── pwd.md │ ├── pwdhist.md │ ├── random.md │ ├── self.md │ ├── shell.md │ ├── tmpdir.md │ └── user.md ├── docs_test.go ├── examples ├── appsize.mx ├── arrays-as-parameters.mx ├── dictionary-api.mx ├── examples_test.go ├── flags.mx ├── foreach.mx ├── hello-world.mx ├── inline-sql.mx ├── loops-iteration.mx ├── table-indexes.mx └── try-catch.mx ├── flags.go ├── gen ├── apis-md-cat.inc.md ├── apis-md-doc.tmpl ├── blog-md-cat.tmpl ├── blog-md-doc.tmpl ├── blog │ ├── map_reading.inc.md │ ├── no_js_here_doc.yaml.unpublished │ ├── reading_lists.chatgpt.md │ ├── reading_lists.inc.md │ ├── reading_lists_doc.yaml │ ├── split_personalities.inc.md │ ├── split_personalities_doc.yaml │ ├── wasm_electron_future_doc.yaml.unpublished │ ├── what_makes_a_good_shell_doc.yaml.unpublished │ ├── whats_in_a_name_doc.yaml.unpublished │ └── why_create_a_new_shell_doc.yaml.unpublished ├── changelog-md-cat.tmpl ├── changelog-md-doc.tmpl ├── changelog │ ├── v2.0_doc.yaml │ ├── v2.10_doc.yaml │ ├── v2.11_doc.yaml │ ├── v2.1_doc.yaml │ ├── v2.2_doc.yaml │ ├── v2.3_doc.yaml │ ├── v2.4_doc.yaml │ ├── v2.5_doc.yaml │ ├── v2.6_doc.yaml │ ├── v2.7_doc.yaml │ ├── v2.8_doc.yaml │ ├── v2.9_doc.yaml │ ├── v3.0_doc.yaml │ ├── v3.1_doc.yaml │ ├── v4.0_doc.yaml │ ├── v4.1_doc.yaml │ ├── v4.2_doc.yaml │ ├── v4.3_doc.yaml │ ├── v4.4_doc.yaml │ ├── v5.0.inc.md │ ├── v5.0_doc.yaml │ ├── v5.1.inc.md │ ├── v5.1_doc.yaml │ ├── v5.2.inc.md │ ├── v5.2_doc.yaml │ ├── v5.3.inc.md │ ├── v5.3_doc.yaml │ ├── v6.0.inc.md │ ├── v6.0_doc.yaml │ ├── v6.1.inc.md │ ├── v6.1_doc.yaml │ ├── v6.2.inc.md │ ├── v6.2_doc.yaml │ ├── v6.3.inc.md │ ├── v6.3_doc.yaml │ ├── v6.4.inc.md │ └── v6.4_doc.yaml ├── commands-go-cat.tmpl ├── commands-md-cat.inc.md ├── commands-md-cat.tmpl ├── commands-md-doc.tmpl ├── commands-vue-cat.tmpl ├── docgen.yaml ├── events-md-cat.inc.md ├── events-md-cat.tmpl ├── events-md-doc.tmpl ├── examples │ ├── json-merge-nushell.inc.md │ └── json-merge-nushell_doc.yaml ├── expr │ ├── add-with-op_doc.yaml │ ├── addition-op_doc.yaml │ ├── assign-merge-op_doc.yaml │ ├── divide-by-op_doc.yaml │ ├── division-op_doc.yaml │ ├── elvis-op_doc.yaml │ ├── multiplication-op_doc.yaml │ ├── multiply-by-op_doc.yaml │ ├── null-coalescing-op_doc.yaml │ ├── subtract-by-op_doc.yaml │ └── subtraction-op_doc.yaml ├── gen_test.go ├── includes │ ├── autogenerated.mkarray.inc.md │ ├── c-style-valid-fun.inc.md │ ├── command-types.inc.md │ ├── event-payload-summary.inc.md │ ├── event-return-summary.inc.md │ ├── events-namespacing.inc.md │ ├── expr-operators-tokens.inc.md │ ├── expr-strict-types-assignment.inc.md │ ├── expr-strict-types.inc.md │ ├── fid-kill.inc.md │ ├── fileref-module-strings.inc.md │ ├── for-loop-json-tips.inc.md │ ├── get-post-method.inc.md │ ├── math.inc.md │ ├── meta-values.inc.md │ ├── mkarray-range-description.inc.md │ ├── mkarray-range-usage.inc.md │ ├── named-pipes.inc.md │ ├── order-of-precedence.inc.md │ ├── package-modules.inc.md │ ├── parser-var-tokens.inc.md │ ├── this-is-a-reserved-var.inc.md │ └── variables.inc.md ├── integrations-md-cat.tmpl ├── integrations-md-doc.tmpl ├── integrations │ ├── chatgpt_doc.yaml │ ├── cheatsh_doc.yaml │ ├── direnv_doc.yaml │ ├── iterm2_doc.yaml │ ├── kitty_doc.yaml │ ├── make_doc.yaml │ ├── man_doc.yaml │ ├── spellcheck_doc.yaml │ ├── terminology_doc.yaml │ └── yarn_doc.yaml ├── mkarray-inc-cat.tmpl ├── mkarray-md-doc.tmpl ├── murex-md-cat.tmpl ├── optionals-md-cat.inc.md ├── parser-md-cat.inc.md ├── parser-md-cat.tmpl ├── parser-md-doc.tmpl ├── parser-vue-cat.tmpl ├── parser │ ├── c-style-functions_doc.yaml │ ├── codeblock-nesting.inc.md │ ├── codeblock_doc.yaml │ ├── create_array_doc.yaml │ ├── create_object_doc.yaml │ ├── expr-inlined_doc.yaml │ ├── lambda_doc.yaml │ ├── logical_ops_doc.yaml │ ├── pipes_doc.yaml │ ├── quotes_doc.yaml │ └── variables_doc.yaml ├── root-md-doc.tmpl ├── root │ ├── CONTRIBUTING.inc.md │ ├── CONTRIBUTING_doc.yaml │ ├── DOWNLOAD.inc.md │ ├── DOWNLOAD_doc.yaml │ ├── INSTALL.inc.md │ ├── INSTALL_doc.yaml │ ├── README.inc.md │ ├── README_doc.yaml │ ├── compatibility.inc.md │ ├── compatibility_doc.yaml │ ├── supported-platforms.inc.md │ ├── supported-platforms_doc.yaml │ ├── tour.inc.md │ └── tour_doc.yaml ├── types-md-cat.inc.md ├── types-md-doc.tmpl ├── user-guide │ ├── ansi_doc.yaml │ ├── arrays.inc.md │ ├── arrays_doc.yaml │ ├── bang-prefix_doc.yaml │ ├── data-types.inc.md │ ├── data-types.yaml │ ├── fileref_doc.yaml │ ├── hint-text-overview.inc.md │ ├── hint-text.inc.md │ ├── hint-text_doc.yaml │ ├── integrations.inc.md │ ├── integrations_doc.yaml │ ├── interactive-shell.inc.md │ ├── interactive-shell_doc.yaml │ ├── job-control.inc.md │ ├── job-control_doc.yaml │ ├── modules_doc.yaml │ ├── named-pipes_doc.yaml │ ├── operators-tokens_doc.yaml │ ├── pipeline_doc.yaml │ ├── profile_doc.yaml │ ├── reserved_vars_doc.yaml │ ├── rosetta-stone.inc.md │ ├── rosetta-stone_doc.yaml │ ├── schedulers_doc.yaml │ ├── scoping_doc.yaml │ ├── strict-types_doc.yaml │ ├── terminal-keys.inc.md │ └── terminal-keys_doc.yaml ├── userguide-md-cat.tmpl.md ├── userguide-md-doc.tmpl ├── userguide-vue-cat.tmpl ├── variables-md-cat.inc.md ├── variables-md-cat.tmpl ├── variables-md-doc.tmpl ├── variables-vue-cat.tmpl ├── variables │ ├── ARGV_doc.yaml │ ├── COLUMNS_doc.yaml │ ├── EVENT_RETURN_doc.yaml │ ├── HOME_doc.yaml │ ├── HOSTNAME_doc.yaml │ ├── LINES_doc.yaml │ ├── LOGNAME_doc.yaml │ ├── MUREX_ARGV_doc.yaml │ ├── MUREX_EXE_doc.yaml │ ├── OLDPWD_doc.yaml │ ├── PARAMS_doc.yaml │ ├── PWDHIST_doc.yaml │ ├── PWD_doc.yaml │ ├── RANDOM_doc.yaml │ ├── SELF_doc.yaml │ ├── SHELL_doc.yaml │ ├── TMPDIR_doc.yaml │ ├── USER_doc.yaml │ ├── meta-values_doc.yaml │ └── numeric_doc.yaml ├── vuepress │ ├── commands_generated.json │ ├── config.ts │ ├── navbar.ts │ ├── parser_generated.json │ ├── public │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── download.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── favicon.svg │ │ ├── git-autocomplete.png │ │ ├── keyboard.png │ │ ├── murex-logo-shell.svg │ │ ├── murex.svg │ │ ├── og-murex-v1.png │ │ ├── og-murex-v2.png │ │ ├── og-murex-v3.png │ │ ├── rosetta.svg │ │ ├── screenshot-autocomplete-context-sensitive.png │ │ ├── screenshot-autocomplete-git.png │ │ ├── screenshot-error-messages.png │ │ ├── screenshot-hint-starship.png │ │ ├── screenshot-hint-text-egrep.png │ │ ├── screenshot-hint-text-rsync.png │ │ ├── screenshot-hint-text-uptime.png │ │ ├── screenshot-history.png │ │ ├── screenshot-kill-autocomplete.png │ │ ├── screenshot-open-foreach.png │ │ ├── screenshot-paste-safety.png │ │ ├── screenshot-preview-command-line.png │ │ ├── screenshot-preview-custom-hints.png │ │ ├── screenshot-preview-image.png │ │ ├── screenshot-preview-man-page.png │ │ ├── screenshot-preview-man-rsync.png │ │ ├── screenshot-ps-select.png │ │ ├── screenshot-spellchecker.png │ │ ├── screenshot-supports-posix.png │ │ └── site.webmanifest │ ├── sidebar.ts │ ├── styles │ │ ├── config.scss │ │ ├── index.scss │ │ └── palette.scss │ ├── theme.ts │ ├── userguide_generated.json │ └── variables_generated.json └── website │ ├── 404.md │ ├── assets │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ └── style.css │ ├── find-exec.mx │ ├── footer.html │ ├── header.html │ ├── testcases.svg │ ├── version.svg │ └── wasm │ └── index.html ├── go.mod ├── go.sum ├── godoc.go ├── images ├── blog │ └── split_personalities │ │ ├── conflict.png │ │ ├── murex.png │ │ ├── new.jpg │ │ ├── old.jpg │ │ └── thompson.jpg ├── screenshot-autocomplete-context-sensitive.png ├── screenshot-autocomplete-git.png ├── screenshot-error-messages.png ├── screenshot-hint-starship.png ├── screenshot-hint-text-rsync.png ├── screenshot-history.png ├── screenshot-iterm2-open.png ├── screenshot-kill-autocomplete.png ├── screenshot-kitty-open.png ├── screenshot-open-foreach.png ├── screenshot-paste-safety.png ├── screenshot-preview-command-line.png ├── screenshot-preview-custom-hints.png ├── screenshot-preview-image.png ├── screenshot-preview-man-page.png ├── screenshot-preview-man-rsync.png ├── screenshot-ps-select.png ├── screenshot-spellchecker.png ├── screenshot-supports-posix.png ├── screenshot-terminology-open.png └── website-badge.svg ├── integrations ├── _namespaces_any.mx ├── aspell_any.mx ├── aws_any.mx ├── bash_posix.mx ├── chatgpt_any.mx ├── cheat.sh_any.mx ├── coreutils_any.mx ├── coreutils_posix.mx ├── dd_posix.mx ├── docker-compose_any.mx ├── docker_any.mx ├── find_any.mx ├── git_any.mx ├── go_any.mx ├── go_plan9.mx ├── go_posix.mx ├── go_windows.mx ├── godoc.go ├── gopass_any.mx ├── gping_any.mx ├── helix-editor_posix.mx ├── homebrew_darwin.mx ├── make_posix.mx ├── man_posix.mx ├── microk8s_any.mx ├── mxtty_posix.mx ├── orbstack_darwin.mx ├── signals_posix.mx ├── ssh_posix.mx ├── su_linux.mx ├── systemctl_linux.mx ├── terraform-docs_any.mx ├── terraform_any.mx ├── tmux_posix.mx ├── tset_posix.mx ├── vscode.mx ├── yarn_any.mx ├── yay_linux.mx ├── zfs_posix.mx ├── zzz_example_any.mx ├── zzz_example_darwin.mx ├── zzz_example_dragonfly.mx ├── zzz_example_freebsd.mx ├── zzz_example_linux.mx ├── zzz_example_netbsd.mx ├── zzz_example_openbsd.mx ├── zzz_example_plan9.mx ├── zzz_example_posix.mx ├── zzz_example_solaris.mx ├── zzz_example_windows.mx ├── zzz_integrations.go ├── zzz_integrations_any.go ├── zzz_integrations_darwin.go ├── zzz_integrations_dragonfly.go ├── zzz_integrations_freebsd.go ├── zzz_integrations_linux.go ├── zzz_integrations_netbsd.go ├── zzz_integrations_openbsd.go ├── zzz_integrations_plan9.go ├── zzz_integrations_posix.go ├── zzz_integrations_solaris.go └── zzz_integrations_windows.go ├── lang ├── aliases.go ├── aliases_test.go ├── define_array.go ├── define_array_type.go ├── define_array_type_test.go ├── define_dump.go ├── define_element_object.go ├── define_element_object_test.go ├── define_getters.go ├── define_getters_test.go ├── define_index_objects.go ├── define_index_tables.go ├── define_index_tables_test.go ├── define_map.go ├── define_marshal.go ├── define_marshal_doc.yaml ├── define_marshal_test.go ├── define_mime.go ├── define_mime_test.go ├── define_setters.go ├── define_unmarshal.go ├── define_unmarshal_doc.yaml ├── define_unmarshal_test.go ├── deprecated.go ├── errors.go ├── exec.go ├── exec_js.go ├── exec_notwin.go ├── exec_plan9.go ├── exec_test.go ├── exec_unix.go ├── exec_windows.go ├── exit.go ├── expressions │ ├── ast.go │ ├── ast_test.go │ ├── block.go │ ├── block_test.go │ ├── errors.go │ ├── errors_test.go │ ├── execute.go │ ├── execute_test.go │ ├── exp00_generics.go │ ├── exp00_test.go │ ├── exp03.go │ ├── exp03_test.go │ ├── exp04.go │ ├── exp04_test.go │ ├── exp06.go │ ├── exp06_test.go │ ├── exp07.go │ ├── exp07_test.go │ ├── exp11.go │ ├── exp12.go │ ├── exp13.go │ ├── exp13_test.go │ ├── exp14.go │ ├── exp14_test.go │ ├── expression.go │ ├── expression_test.go │ ├── functions │ │ ├── function.go │ │ └── functions_test.go │ ├── globbing.go │ ├── globbing_test.go │ ├── noglob │ │ ├── noglob.go │ │ └── noglob_test.go │ ├── parameters_test.go │ ├── parse_array.go │ ├── parse_array_test.go │ ├── parse_bareword.go │ ├── parse_bareword_test.go │ ├── parse_block.go │ ├── parse_block_test.go │ ├── parse_boolean_test.go │ ├── parse_comment.go │ ├── parse_comment_test.go │ ├── parse_expression.go │ ├── parse_expression_test.go │ ├── parse_function.go │ ├── parse_function_test.go │ ├── parse_lambda.go │ ├── parse_lambda_test.go │ ├── parse_number.go │ ├── parse_number_test.go │ ├── parse_object.go │ ├── parse_object_test.go │ ├── parse_object_types.go │ ├── parse_quote%_test.go │ ├── parse_quote1_test.go │ ├── parse_quote2_test.go │ ├── parse_quoteBQ_test.go │ ├── parse_quoteBT_test.go │ ├── parse_quoteP_test.go │ ├── parse_quotes.go │ ├── parse_statement.go │ ├── parse_statement_test.go │ ├── parse_subshell.go │ ├── parse_subshell_test.go │ ├── parse_switch.go │ ├── parse_switch_test.go │ ├── parse_vars.go │ ├── parse_vars_exec_test.go │ ├── parse_vars_test.go │ ├── primitives │ │ ├── primitive_string.go │ │ ├── primitives.go │ │ └── primitives_test.go │ ├── statement.go │ ├── statement_rules.go │ ├── symbols │ │ ├── exp.go │ │ └── exp_string.go │ ├── testcode │ │ ├── testcode_ac_config.mx │ │ ├── testcode_ac_element.mx │ │ ├── testcode_ac_index.mx │ │ ├── testcode_aws.mx │ │ ├── testcode_if_else_fn.mx │ │ ├── testcode_microk8s.mx │ │ ├── testcode_mkmodule.mx │ │ ├── testcode_murex-dev.mx │ │ ├── testcode_oa_image.mx │ │ ├── testcode_progress.mx │ │ └── testcode_yarn.mx │ ├── validate.go │ ├── variables.go │ └── variables_test.go ├── fork.go ├── fork_management.go ├── fork_release.go ├── fork_trace.go ├── funcid.go ├── funcid_test.go ├── functions.go ├── functions_fuzz_test.go ├── functions_test.go ├── godoc.go ├── init.go ├── interpreter.go ├── interpreter_js.go ├── interpreter_pc.go ├── interpreter_test.go ├── ipc │ ├── cred.go │ ├── ipc_fallback.go │ └── ipc_unix.go ├── jobs.go ├── jobs_helper_test.go ├── jobs_test.go ├── methods.go ├── methods_test.go ├── parameters │ ├── flags.go │ ├── flags_test.go │ ├── get.go │ ├── get_test.go │ ├── godoc.go │ ├── set.go │ └── tokens.go ├── pipes │ ├── godoc.go │ ├── namedpipes.go │ └── namedpipes_test.go ├── preview.go ├── privates.go ├── process.go ├── process │ ├── background.go │ ├── background_test.go │ ├── name.go │ ├── name_test.go │ ├── sysproc.go │ └── sysproc_test.go ├── process_fallback.go ├── process_mx_test.go ├── process_structs.go ├── process_structs_test.go ├── process_test.go ├── process_unix.go ├── redirection.go ├── redirection_test.go ├── ref │ ├── godoc.go │ └── ref.go ├── runmode │ ├── godoc.go │ ├── runmode.go │ ├── runmode_string.go │ └── runmode_test.go ├── state │ ├── functionstate.go │ ├── functionstate_string.go │ ├── functionstate_test.go │ ├── godoc.go │ ├── state.go │ └── state_test.go ├── stdio │ ├── interface_aw.go │ ├── interface_doc.yaml │ ├── interface_io.go │ ├── register.go │ ├── templates.go │ └── types.go ├── test_compare.go ├── test_compare_stdio.go ├── test_compare_test.go ├── test_messages.go ├── test_results.go ├── test_states.go ├── test_structs.go ├── test_test.go ├── test_units.go ├── test_units_func_test.go ├── test_units_nil_test.go ├── test_units_stdio.go ├── test_units_test.go ├── testdata │ └── fuzz │ │ └── FuzzParseBlock │ │ ├── 2f9cea1e9a87753170ba83bb2697966710f24cb2bdb250a4e9413e3ce93168d0 │ │ ├── 9a3a0cf65df96f395f456353ed7df0dc1b6ecb660c92d2bc8abfaa135f03f1cb │ │ └── a54bd97ce43e403dbed2cb42e802a2bd230c78809a69352d33d224bd29e8d81f ├── trace_disabled.go ├── trace_enabled.go ├── types │ ├── convert.go │ ├── convert_boolean_test.go │ ├── convert_codeblock_test.go │ ├── convert_float2string_test.go │ ├── convert_float_test.go │ ├── convert_generic_test.go │ ├── convert_integer_test.go │ ├── convert_json_test.go │ ├── convert_jsonlines_test.go │ ├── convert_null_test.go │ ├── convert_number_test.go │ ├── convert_string_test.go │ ├── convert_test.go │ ├── datatype.go │ ├── flatten.go │ ├── groups.go │ ├── map2table.go │ ├── table2map.go │ ├── types.go │ ├── types_runes_test.go │ └── types_test.go ├── variables.go ├── variables_bugfix_test.go ├── variables_dot_test.go ├── variables_module.go ├── variables_mx_test.go ├── variables_mxinterface.go ├── variables_reserved.go ├── variables_reserved_test.go └── variables_test.go ├── main.go ├── main_js.go ├── main_plan9.go ├── main_test.go ├── main_unix.go ├── main_windows.go ├── package.json ├── pprof.go ├── shell ├── aspell_test.go ├── autocomplete │ ├── README.md │ ├── autobranch.go │ ├── autocomplete.go │ ├── dynamic.go │ ├── dynamic_cache.go │ ├── execs.go │ ├── execs_plan9.go │ ├── execs_unix.go │ ├── execs_windows.go │ ├── flags.go │ ├── flags_test.go │ ├── format.go │ ├── format_test.go │ ├── globals.go │ ├── paths.go │ ├── paths_cache.go │ ├── paths_plan9.go │ ├── paths_unix.go │ ├── paths_windows.go │ ├── sort.go │ └── sort_test.go ├── godoc.go ├── hint.go ├── hint_fuzz_test.go ├── hint_test.go ├── hintsummary │ ├── class.go │ ├── class_test.go │ ├── readlink.go │ └── summary.go ├── history.go ├── history │ ├── colon.go │ ├── colon_test.go │ ├── history.go │ ├── history_test.go │ ├── vars.go │ └── vars_test.go ├── history_js.go ├── parser.go ├── preview.go ├── preview_cmdline.go ├── preview_command.go ├── preview_dynamic.go ├── preview_error.go ├── preview_fallback.go ├── preview_file.go ├── preview_parameter.go ├── preview_unix.go ├── prompt.go ├── session │ ├── session_fallback.go │ └── session_unix.go ├── shell.go ├── shell_test.go ├── signal_handler │ ├── sigfns │ │ ├── sigfns.go │ │ ├── sigfns_plan9.go │ │ ├── sigfns_unix.go │ │ └── sigfns_windows.go │ ├── signals.go │ ├── signals_js.go │ ├── signals_plan9.go │ ├── signals_unix.go │ └── signals_windows.go ├── syntax.go ├── syntax_fuzz_test.go ├── syntax_test.go ├── tab.go ├── testdata │ └── fuzz │ │ └── FuzzHint │ │ └── 4928df59d7758237bb59628f7c309030600da0fc130846fb7a56342ffe323871 └── variables │ ├── expand.go │ └── expand_test.go ├── source.go ├── source_test.go ├── test ├── boolean.go ├── boolean_test.go ├── build_all_platforms.mx ├── buildserver │ ├── README.md │ ├── build │ ├── build.env │ ├── ci │ └── ci.env ├── ci-murex.sh ├── ci-website.sh ├── count │ ├── count.go │ ├── count_test.go │ ├── godoc.go │ └── server │ │ ├── handler.go │ │ ├── server.go │ │ └── server_test.go ├── exists.go ├── external.go ├── external_test.go ├── fd.sh ├── file name ├── fox.txt ├── fox_crlf.txt ├── methods.go ├── murex.go ├── murex_test.go ├── pre-commit ├── pre-push ├── source.mx ├── source.mx.gz ├── tmp │ └── README ├── types.go └── vim.txt ├── utils ├── README.md ├── alter │ ├── alter.go │ ├── alter_test.go │ ├── convert.go │ ├── merge.go │ ├── merge_test.go │ ├── splitpath.go │ ├── splitpath_test.go │ ├── sum.go │ └── sum_test.go ├── ansi │ ├── ansi.go │ ├── ansi_test.go │ ├── codes │ │ ├── codes.go │ │ └── godoc.go │ ├── consts.go │ ├── getconsts.go │ ├── getconsts_test.go │ └── godoc.go ├── ansititle │ ├── ansititle_fuzz_test.go │ ├── ansititle_js.go │ ├── ansititle_plan9.go │ ├── ansititle_test.go │ ├── ansititle_unix.go │ ├── ansititle_windows.go │ ├── godoc.go │ └── write.go ├── cache │ ├── cache.go │ ├── cachedb │ │ ├── cachedb.go │ │ ├── clear.go │ │ ├── lib_c.go │ │ ├── lib_go.go │ │ ├── list.go │ │ └── trim.go │ ├── config.go │ ├── hash.go │ ├── internal.go │ ├── namespaces.go │ ├── ttl.go │ ├── with_db.go │ └── without_db.go ├── cd │ ├── cache │ │ ├── cache.go │ │ ├── godoc.go │ │ └── timeouts.go │ ├── cd.go │ ├── cd_test.go │ └── godoc.go ├── consts │ ├── consts.go │ ├── consts_test.go │ ├── consts_unix.go │ ├── consts_windows.go │ ├── godoc.go │ └── temp.go ├── counter │ ├── counter.go │ ├── counter_test.go │ └── godoc.go ├── crash │ ├── disable.go │ └── handler.go ├── dedup │ ├── dedup.go │ ├── dedup_test.go │ └── godoc.go ├── docgen │ ├── LICENSE │ ├── README.md │ ├── api │ │ ├── category.go │ │ ├── config.go │ │ ├── document.go │ │ ├── filesystem.go │ │ ├── functions.go │ │ ├── godoc.go │ │ ├── logging.go │ │ ├── render.go │ │ ├── templates.go │ │ ├── unique.go │ │ └── unmarshaller.go │ ├── godoc.go │ ├── main.go │ └── main_test.go ├── envvars │ ├── envvars.go │ ├── envvars_test.go │ └── godoc.go ├── escape │ ├── escape.go │ ├── escape_test.go │ └── godoc.go ├── exists.go ├── exists_test.go ├── home │ ├── godoc.go │ ├── home.go │ ├── home_js.go │ └── home_test.go ├── humannumbers │ ├── bytes.go │ ├── columnletter.go │ ├── columnletter_test.go │ ├── godoc.go │ ├── ordinal.go │ └── ordinal_test.go ├── inject │ ├── godoc.go │ ├── inject.go │ ├── inject_fuzz_test.go │ └── inject_test.go ├── json │ ├── godoc.go │ ├── invalid_test.go │ ├── lazy.go │ ├── lazy_test.go │ ├── marshal.go │ ├── marshal_test.go │ ├── unmarshal.go │ ├── unmarshal_fuzz_test.go │ ├── unmarshal_test.go │ └── valid_test.go ├── lists │ ├── count.go │ ├── count_test.go │ ├── crop.go │ ├── crop_test.go │ ├── generics.go │ ├── generics_test.go │ ├── godoc.go │ ├── match.go │ ├── match_test.go │ ├── remove.go │ ├── remove_test.go │ ├── sum.go │ └── sum_test.go ├── man │ ├── descriptions_linux.go │ ├── descriptions_posix.go │ ├── descriptions_test.go │ ├── descriptions_unix.go │ ├── flags_cache.go │ ├── godoc.go │ ├── man_test.go │ ├── man_unix.go │ ├── man_windows.go │ ├── man_windows_test.go │ ├── summary_test.go │ ├── summary_unix.go │ ├── test_cat.1.gz │ ├── test_cat.txt │ ├── test_cp.1.gz │ ├── test_cp.txt │ ├── test_find.1.gz │ ├── test_find.txt │ ├── test_git-commit.1.gz │ ├── test_git-commmit.txt │ ├── test_ls.1.gz │ ├── test_ls.txt │ ├── test_ssh.1.gz │ └── test_ssh.txt ├── mxjson │ ├── godoc.go │ ├── invalid_test.go │ ├── mxvalid_test.go │ ├── parser.go │ ├── parser_fuzz_test.go │ ├── parser_test.go │ ├── structs.go │ ├── structs_test.go │ ├── testdata │ │ └── fuzz │ │ │ └── FuzzParser │ │ │ └── 82028ed5c60310bba0f811c32cc8524ce8b953755e4d634e79719f65438cb2c5 │ └── valid_test.go ├── objectkeys │ └── objectkeys.go ├── parser │ ├── godoc.go │ ├── highlight_test.go │ ├── parser.go │ ├── parser_fuzz_test.go │ ├── parser_test.go │ ├── pipetoken_string.go │ ├── pipetoken_test.go │ ├── safe.go │ ├── safe_test.go │ ├── unsafe.go │ └── unsafe_test.go ├── path │ ├── join.go │ ├── join_test.go │ ├── marshal.go │ └── split.go ├── path_posix.go ├── path_test.go ├── path_windows.go ├── pathsplit │ ├── godoc.go │ ├── pathsplit.go │ └── pathsplit_test.go ├── posix.go ├── posix │ ├── godoc.go │ ├── posix.go │ └── posix_test.go ├── readall │ ├── godoc.go │ ├── readall.go │ └── readall_test.go ├── readline │ ├── cache.go │ ├── cache_test.go │ ├── codes.go │ ├── cursor.go │ ├── editor.go │ ├── editor_js.go │ ├── editor_plan9.go │ ├── editor_unix.go │ ├── editor_windows.go │ ├── errors.go │ ├── events.go │ ├── examples │ │ └── 01-getting-started │ │ │ └── LICENSE │ ├── find.go │ ├── godoc.go │ ├── hint.go │ ├── history.go │ ├── hotkey_functions.go │ ├── hotkey_recall.go │ ├── instance.go │ ├── preview.go │ ├── preview_test.go │ ├── raw │ │ └── LICENSE │ ├── raw_bsd.go │ ├── raw_js.go │ ├── raw_linux.go │ ├── raw_plan9.go │ ├── raw_solaris.go │ ├── raw_unix.go │ ├── raw_windows.go │ ├── read.go │ ├── read_js.go │ ├── read_test.go │ ├── read_tty.go │ ├── readline.go │ ├── runecache.go │ ├── signal_fallback.go │ ├── signal_unix.go │ ├── suggestions.go │ ├── syntax.go │ ├── tab.go │ ├── tabfind.go │ ├── tabgrid.go │ ├── tabgrid_test.go │ ├── tabmap.go │ ├── term.go │ ├── timer.go │ ├── tokenise.go │ ├── undo.go │ ├── unicode.go │ ├── unicode_test.go │ ├── update.go │ ├── vim.go │ ├── vimdelete.go │ ├── vimdelete_test.go │ ├── write.go │ ├── write_js.go │ ├── write_test.go │ └── write_tty.go ├── rmbs │ ├── rmbs.go │ └── rmbs_test.go ├── semver │ ├── semver.go │ └── semver_test.go ├── spellcheck │ ├── godoc.go │ ├── highlight.go │ ├── highlight_test.go │ ├── spellcheck.go │ ├── spellcheck_test.go │ └── userdictionary │ │ ├── godoc.go │ │ ├── userdictionary.go │ │ └── userdictionary_test.go ├── tmpfile.go ├── trim.go ├── trim_test.go ├── url.go ├── url_test.go ├── virtualterm │ ├── export.go │ ├── export_test.go │ ├── flags.go │ ├── godoc.go │ ├── term.go │ ├── term_test.go │ ├── write.go │ └── write_test.go ├── wasmserver │ ├── godoc.go │ ├── main.go │ └── main_test.go ├── which │ ├── godoc.go │ ├── path.go │ ├── path_windows.go │ ├── which.go │ └── which_test.go └── windows.go └── version.svg /.github/ISSUE_TEMPLATE/autocomplete-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Autocomplete request 3 | about: Suggest a missing autocomplete 4 | title: 'autocomplete: ' 5 | labels: autocomplete 6 | assignees: '' 7 | 8 | --- 9 | 10 | **What is the name of the CLI command:** 11 | eg `yarn` 12 | 13 | **What the application is used for:** 14 | Provide a little context to the utility of this command (just in case it is uncommon and requires a little more effort discovering) 15 | 16 | **Describe why the default autocompletions are inadequate:** 17 | This can also help us improve how the defaults are auto-generated 18 | -------------------------------------------------------------------------------- /behavioural/alias_len.mx: -------------------------------------------------------------------------------- 1 | # This file tests the alias `len` is set 2 | 3 | function alias.len { 4 | a: [1..5] -> len 5 | } 6 | 7 | test: unit function alias.len %{ 8 | StdoutMatch: "5" 9 | DataType: num 10 | ExitNum: 0 11 | } 12 | -------------------------------------------------------------------------------- /behavioural/cast.mx: -------------------------------------------------------------------------------- 1 | # This file tests murex data types are being cast 2 | 3 | function cast.test.worker { 4 | sleep 2 5 | -> :foo debug -> [[ /Data-Type/Murex ]] 6 | } 7 | 8 | function cast.test { 9 | tout bar rab -> cast.test.worker 10 | } 11 | 12 | test: unit function cast.test { 13 | "StdoutMatch": "foo", 14 | "ExitNum": 0 15 | } -------------------------------------------------------------------------------- /behavioural/event_cc_panic.mx: -------------------------------------------------------------------------------- 1 | # This tests we don't see a panic 2 | 3 | if { os posix } then { 4 | 5 | function event.cc.panic.posix { 6 | event onCommandCompletion event.cc.panic.posix=echo { 7 | # do nothing 8 | } 9 | 10 | exec echo test 11 | } 12 | 13 | test: unit function event.cc.panic.posix { 14 | "StdoutMatch": "test\n", 15 | "ExitNum": 0, 16 | "StderrRegex": "Error" 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /behavioural/exec_data_types.mx.resource: -------------------------------------------------------------------------------- 1 | # This file tests murex data types are being sent and received across `exec` process boundaries 2 | 3 | -> debug -> [[ /Data-Type/Murex ]] -------------------------------------------------------------------------------- /behavioural/exec_data_types.sh.resource: -------------------------------------------------------------------------------- 1 | # This file tests murex data types are being sent and received across `exec` process boundaries 2 | 3 | echo $MUREX_DATA_TYPE -------------------------------------------------------------------------------- /behavioural/export_crash.mx: -------------------------------------------------------------------------------- 1 | # This file tests https://github.com/lmorg/murex/issues/824 2 | 3 | function export.crashes { 4 | export A_very_long_string_that_shouldnt_exist_lkjsafasdjoirfjoiwedjowqdiuqehdiwefj 5 | } 6 | 7 | test unit function export.crashes %{ 8 | StderrRegex: " variable '.*?' does not exist" 9 | DataType: str 10 | ExitNum: 1 11 | } 12 | -------------------------------------------------------------------------------- /behavioural/onSignalReceived.mx: -------------------------------------------------------------------------------- 1 | function signal.SIGUSR1.trap { 2 | bg { 3 | exec $MUREX_EXE -c %( 4 | event onSignalReceived example=SIGUSR1 { 5 | out "SIGUSR1 received..." 6 | } 7 | 8 | out "waiting for signal..." 9 | sleep 5 10 | ) 11 | } 12 | sleep 2 # just in case `exec` hasn't started yet 13 | signal $MOD.SIGNAL_TRAP_PID SIGUSR1 14 | } 15 | 16 | test unit function signal.SIGUSR1.trap %{ 17 | StdoutMatch: "waiting for signal...\nSIGUSR1 received...\n" 18 | DataType: str 19 | ExitNum: 0 20 | } -------------------------------------------------------------------------------- /behavioural/quiet_flag.mx: -------------------------------------------------------------------------------- 1 | # This file tests -quiet flag 2 | 3 | function quiet-flag-enabled { 4 | exec $MUREX_EXE --quiet --load-modules -c "out fin" 5 | } 6 | 7 | test unit function quiet-flag-enabled %{ 8 | StdoutMatch: "fin\n" 9 | StderrMatch: "" 10 | ExitNum: 0 11 | } 12 | 13 | function quiet-flag-disabled { 14 | exec $MUREX_EXE --load-modules -c "out fin" 15 | } 16 | 17 | test unit function quiet-flag-disabled %{ 18 | StdoutMatch: "fin\n" 19 | StderrRegex: 'Loading profile' 20 | ExitNum: 0 21 | } -------------------------------------------------------------------------------- /behavioural/return.mx: -------------------------------------------------------------------------------- 1 | # This file tests return exits scope correctly 2 | 3 | function return.nonzero { 4 | out "goodbye" 5 | return 13 6 | } 7 | 8 | test: unit function return.nonzero %{ 9 | StdoutMatch: "goodbye\n" 10 | DataType: str 11 | ExitNum: 13 12 | } 13 | -------------------------------------------------------------------------------- /behavioural/try_control.mx: -------------------------------------------------------------------------------- 1 | # control 2 | 3 | function: control.scope.block.fn.fail { 4 | a: [1..2] -> foreach i { err: $i | out: bar } 5 | } 6 | 7 | test: unit function control.scope.block.fn.fail { 8 | "StderrMatch": "1\n2\n", 9 | "StdoutMatch": "bar\nbar\n" 10 | } 11 | 12 | function: control.runmode.fail { 13 | out "foo" 14 | runmode try function 15 | out "bar" 16 | } 17 | 18 | test: unit function control.runmode.fail { 19 | "StdoutMatch": "foo\nbar\n", 20 | "StderrRegex": "should only be used as the first statement in a block", 21 | "ExitNum": 0 22 | } 23 | -------------------------------------------------------------------------------- /builtins/core/arraytools/2darray_test.go: -------------------------------------------------------------------------------- 1 | package arraytools_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins/core/mkarray" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func Test2dArray(t *testing.T) { 11 | tests := []test.MurexTest{{ 12 | Block: `2darray { a: [1..3] } { ja: [Mon..Wed] }`, 13 | Stdout: `[["",""],["1","Mon"],["2","Tue"],["3","Wed"]]`, 14 | }} 15 | 16 | test.RunMurexTests(tests, t) 17 | } 18 | -------------------------------------------------------------------------------- /builtins/core/arraytools/addheading_test.go: -------------------------------------------------------------------------------- 1 | package arraytools_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | /* 11 | ADDHEADING 12 | */ 13 | 14 | func TestAddheadingJsonl(t *testing.T) { 15 | tests := []test.MurexTest{ 16 | { 17 | Block: `tout: jsonl '["Bob", 23, true]' -> addheading name age active`, 18 | Stdout: "[\"name\",\"age\",\"active\"]\n[\"Bob\",\"23\",\"true\"]\n", 19 | }, 20 | } 21 | 22 | test.RunMurexTests(tests, t) 23 | } 24 | -------------------------------------------------------------------------------- /builtins/core/arraytools/godoc.go: -------------------------------------------------------------------------------- 1 | // Package arraytools provides functions for working with arrays and maps 2 | package arraytools 3 | -------------------------------------------------------------------------------- /builtins/core/arraytools/map_test.go: -------------------------------------------------------------------------------- 1 | package arraytools_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins/core/mkarray" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestMap(t *testing.T) { 11 | tests := []test.MurexTest{{ 12 | Block: `map { ja: [1..5] } { a: [Mon..Fri] }`, 13 | Stdout: `{"1":"Mon","2":"Tue","3":"Wed","4":"Thu","5":"Fri"}`, 14 | }} 15 | 16 | test.RunMurexTests(tests, t) 17 | } 18 | -------------------------------------------------------------------------------- /builtins/core/datatools/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `management` 2 | 3 | Package datatools provides utilities for manipulating data structures. -------------------------------------------------------------------------------- /builtins/core/datatools/alter_op_test.go: -------------------------------------------------------------------------------- 1 | package datatools_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins/core/io" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestAlterOp(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `tout json %{a:1, b:2, c:3} ~> %{b:4}`, 14 | Stdout: `{"a":1,"b":4,"c":3}`, 15 | }, 16 | } 17 | 18 | test.RunMurexTests(tests, t) 19 | } 20 | -------------------------------------------------------------------------------- /builtins/core/datatools/godoc.go: -------------------------------------------------------------------------------- 1 | // Package datatools provides utilities for manipulating data structures 2 | package datatools 3 | -------------------------------------------------------------------------------- /builtins/core/escape/README.md: -------------------------------------------------------------------------------- 1 | # Package `escape` 2 | 3 | This provides some handy string escaping utilities 4 | 5 | * `escape` 6 | * `!escape` 7 | * `eschtml` 8 | * `!eschtml` 9 | * `escurl` 10 | * `!escurl` 11 | -------------------------------------------------------------------------------- /builtins/core/escape/godoc.go: -------------------------------------------------------------------------------- 1 | // Package escape provides some handy string escaping utilities 2 | package escape 3 | -------------------------------------------------------------------------------- /builtins/core/httpclient/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `httpclient` 2 | 3 | Useful HTTP functions. This is a dependency for other functions within Murex 4 | -------------------------------------------------------------------------------- /builtins/core/httpclient/godoc.go: -------------------------------------------------------------------------------- 1 | // Package httpclient provides useful HTTP functions 2 | package httpclient 3 | -------------------------------------------------------------------------------- /builtins/core/httpclient/post_test.go: -------------------------------------------------------------------------------- 1 | package httpclient 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang" 7 | "github.com/lmorg/murex/test/count" 8 | ) 9 | 10 | // TestPost tests the post function 11 | func TestPost(t *testing.T) { 12 | count.Tests(t, 1) 13 | 14 | lang.InitEnv() 15 | addr := StartHTTPServer(t) 16 | 17 | p := lang.NewTestProcess() 18 | p.Config = lang.ShellProcess.Config 19 | p.Parameters.DefineParsed([]string{addr}) 20 | 21 | err := cmdPost(p) 22 | if err != nil { 23 | t.Error(err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /builtins/core/httpclient/structs.go: -------------------------------------------------------------------------------- 1 | package httpclient 2 | 3 | import "net/http" 4 | 5 | type metaDomains map[string]metaValues 6 | type metaValues map[string]string 7 | 8 | type httpStatus struct { 9 | Code int 10 | Message string 11 | } 12 | 13 | type jsonHttp struct { 14 | Status httpStatus 15 | Headers http.Header 16 | Body string 17 | } 18 | -------------------------------------------------------------------------------- /builtins/core/io/DUMMYFILE_test.md: -------------------------------------------------------------------------------- 1 | This is just used for testing -------------------------------------------------------------------------------- /builtins/core/io/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `io` 2 | 3 | It is recommended that this is always included because it includes 4 | tools for reading and writing streams. -------------------------------------------------------------------------------- /builtins/core/io/f_test.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test" 7 | ) 8 | 9 | func TestLsF(t *testing.T) { 10 | tests := []test.MurexTest{ 11 | // f 12 | { 13 | Block: "f: +f", 14 | Stdout: "README.md", 15 | }, 16 | } 17 | test.RunMurexTestsRx(tests, t) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/core/io/pt_test.go: -------------------------------------------------------------------------------- 1 | package io_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test" 7 | ) 8 | 9 | func TestPipeTelemetry(t *testing.T) { 10 | tests := []test.MurexTest{ 11 | { 12 | Block: `tout * 12345 -> pt`, 13 | Stdout: `12345`, 14 | }, 15 | } 16 | 17 | test.RunMurexTests(tests, t) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/core/io/read_test.go: -------------------------------------------------------------------------------- 1 | package io_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestRead(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `bg { read: q "?" }; sleep 2`, 14 | Stderr: `background processes cannot read from stdin`, 15 | }, 16 | } 17 | 18 | test.RunMurexTestsRx(tests, t) 19 | } 20 | -------------------------------------------------------------------------------- /builtins/core/io/tmp_test.go: -------------------------------------------------------------------------------- 1 | package io_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins/core/open" 7 | _ "github.com/lmorg/murex/builtins/core/typemgmt" 8 | "github.com/lmorg/murex/test" 9 | ) 10 | 11 | func TestTmp(t *testing.T) { 12 | tests := []test.MurexTest{ 13 | { 14 | Block: ` 15 | out: "foobar" -> tmp -> set: MUREX_TEST_tmp_cmd 16 | open: $MUREX_TEST_tmp_cmd`, 17 | Stdout: "foobar\n", 18 | }, 19 | } 20 | 21 | test.RunMurexTests(tests, t) 22 | } 23 | -------------------------------------------------------------------------------- /builtins/core/lists/msort_test.go: -------------------------------------------------------------------------------- 1 | package lists_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins/core/io" 7 | _ "github.com/lmorg/murex/lang/expressions" 8 | "github.com/lmorg/murex/test" 9 | ) 10 | 11 | func TestMsort(t *testing.T) { 12 | tests := []test.MurexTest{{ 13 | Block: `tout json ([ "b", "c", "a" ]) -> msort`, 14 | Stdout: `["a","b","c"]`, 15 | }} 16 | 17 | test.RunMurexTests(tests, t) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/core/lists/prepend_test.go: -------------------------------------------------------------------------------- 1 | package lists_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestPrependRegressionBug(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `set v = foo; $v -> prepend bar`, 14 | Stdout: "bar\nfoo\n", 15 | }, 16 | { 17 | Block: `set v = foo; $v -> append bar`, 18 | Stdout: "foo\nbar\n", 19 | }, 20 | } 21 | 22 | test.RunMurexTests(tests, t) 23 | } 24 | -------------------------------------------------------------------------------- /builtins/core/management/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `management` 2 | 3 | It is recommended that this is always included because it includes 4 | shell management tools. -------------------------------------------------------------------------------- /builtins/core/management/godoc.go: -------------------------------------------------------------------------------- 1 | // Package management provides misc functions for managing your murex runtime environment 2 | package management 3 | -------------------------------------------------------------------------------- /builtins/core/management/source_test.mx: -------------------------------------------------------------------------------- 1 | out "Hello, world!" -------------------------------------------------------------------------------- /builtins/core/mkarray/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: make array 2 | 3 | This provides the array builtins, `a`, `ja` and `ta`: 4 | 5 | a: [monday..friday] 6 | a: [Jan..Dec] 7 | a: [0..99] 8 | a: [00..09] 9 | a: [z..a] 10 | a: [0000..1000x2] 11 | a: [00..ffx16] 12 | a: [foo,bar] 13 | a: foo[a,b,c..x,y,z]bar 14 | a: [foo,bar][bar,foo] -------------------------------------------------------------------------------- /builtins/core/mkarray/godoc.go: -------------------------------------------------------------------------------- 1 | // Package mkarray provides functions for rapidly building arrays 2 | package mkarray 3 | -------------------------------------------------------------------------------- /builtins/core/open/http.go: -------------------------------------------------------------------------------- 1 | package open 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/lmorg/murex/builtins/core/httpclient" 7 | "github.com/lmorg/murex/lang" 8 | ) 9 | 10 | func http(p *lang.Process, url string) (io.ReadCloser, string, error) { 11 | resp, err := httpclient.Request(p.Context, "GET", url, nil, p.Config, true) 12 | 13 | if err != nil { 14 | return nil, "", err 15 | } 16 | 17 | dt := lang.MimeToMurex(resp.Header.Get("Content-Type")) 18 | 19 | // TODO: insert something about content-length detection 20 | 21 | return resp.Body, dt, nil 22 | } 23 | -------------------------------------------------------------------------------- /builtins/core/openimage/godoc.go: -------------------------------------------------------------------------------- 1 | // Package openimage renders bitmap image data on your terminal 2 | package openimage 3 | -------------------------------------------------------------------------------- /builtins/core/openimage/open-image_test.go: -------------------------------------------------------------------------------- 1 | package openimage_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestOpenImageError(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `trypipe { open-image -> out: foobar }`, 14 | Stdout: `^$`, 15 | Stderr: `expecting to output to the terminal`, 16 | ExitNum: 1, 17 | }, 18 | } 19 | 20 | test.RunMurexTestsRx(tests, t) 21 | } 22 | -------------------------------------------------------------------------------- /builtins/core/pretty/godoc.go: -------------------------------------------------------------------------------- 1 | // Package pretty provides data formatting tools 2 | package pretty 3 | -------------------------------------------------------------------------------- /builtins/core/processes/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `processes` 2 | 3 | It is recommended that this is always included because it includes 4 | shell process management tools. -------------------------------------------------------------------------------- /builtins/core/processes/bgfg_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package processes 5 | 6 | import ( 7 | "errors" 8 | 9 | "github.com/lmorg/murex/lang" 10 | "github.com/lmorg/murex/lang/types" 11 | ) 12 | 13 | func mkbg(p *lang.Process) error { 14 | return errors.New("Invalid parameters. `bg` only supports a code block in js/wasm because processes are running in a sandboxed VM") 15 | } 16 | 17 | func cmdForeground(p *lang.Process) error { 18 | p.Stdout.SetDataType(types.Null) 19 | 20 | return errors.New("This function is currently not supported on js/wasm") 21 | } 22 | 23 | func unstop(p *lang.Process) {} 24 | -------------------------------------------------------------------------------- /builtins/core/processes/godoc.go: -------------------------------------------------------------------------------- 1 | // Package processes provides core functions for managing processes 2 | package processes 3 | -------------------------------------------------------------------------------- /builtins/core/ranges/number.go: -------------------------------------------------------------------------------- 1 | package ranges 2 | 3 | func newNumber(r *rangeParameters) (err error) { 4 | rf, err := createRfIndex(r) 5 | if err != nil { 6 | return err 7 | } 8 | 9 | if rf.start < 0 { 10 | rf.start -= 2 11 | rf.end -= 2 12 | } 13 | 14 | r.Match = rf 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /builtins/core/ranges/string.go: -------------------------------------------------------------------------------- 1 | package ranges 2 | 3 | type rfString struct { 4 | sStart string 5 | sEnd string 6 | } 7 | 8 | func (rf *rfString) Start(b []byte) bool { return string(b) == rf.sStart } 9 | func (rf *rfString) End(b []byte) bool { return string(b) == rf.sEnd } 10 | func (rf *rfString) SetLength(_ int) { /* do nothing */ } 11 | 12 | func newString(r *rangeParameters) error { 13 | rf := new(rfString) 14 | 15 | rf.sStart = r.Start 16 | rf.sEnd = r.End 17 | 18 | r.Match = rf 19 | 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /builtins/core/runtime/godoc.go: -------------------------------------------------------------------------------- 1 | // Package cmdruntime provides data on murex's runtime state 2 | package cmdruntime 3 | -------------------------------------------------------------------------------- /builtins/core/structs/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `structs` 2 | 3 | This package contains all the logic structure functions. eg for/while 4 | blocks and if/else blocks. Disabling it would cripple your shell. -------------------------------------------------------------------------------- /builtins/core/structs/for_test.go: -------------------------------------------------------------------------------- 1 | package structs_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestFor(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `for { $i=1; $i<6; $i=$i+1 } { echo $i }`, 14 | Stdout: "1\n2\n3\n4\n5\n", 15 | }, 16 | } 17 | 18 | test.RunMurexTests(tests, t) 19 | } 20 | -------------------------------------------------------------------------------- /builtins/core/structs/godoc.go: -------------------------------------------------------------------------------- 1 | // Package structs provides code syntax structures for murex 2 | package structs 3 | -------------------------------------------------------------------------------- /builtins/core/system/system_test.go: -------------------------------------------------------------------------------- 1 | package system_test 2 | 3 | import ( 4 | "runtime" 5 | "testing" 6 | 7 | _ "github.com/lmorg/murex/builtins" 8 | "github.com/lmorg/murex/test" 9 | ) 10 | 11 | func TestOs(t *testing.T) { 12 | tests := []test.MurexTest{ 13 | { 14 | Block: `os`, 15 | Stdout: runtime.GOOS, 16 | }, 17 | { 18 | Block: `os bob`, 19 | Stdout: "false", 20 | ExitNum: 1, 21 | }, 22 | { 23 | Block: `os ` + runtime.GOOS, 24 | Stdout: "true", 25 | }, 26 | } 27 | 28 | test.RunMurexTests(tests, t) 29 | } 30 | -------------------------------------------------------------------------------- /builtins/core/system/system_unix_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && !plan9 && !js 2 | // +build !windows,!plan9,!js 3 | 4 | package system_test 5 | 6 | import ( 7 | "testing" 8 | 9 | _ "github.com/lmorg/murex/builtins" 10 | "github.com/lmorg/murex/test" 11 | ) 12 | 13 | func TestOsWindows(t *testing.T) { 14 | tests := []test.MurexTest{ 15 | { 16 | Block: `os windows`, 17 | Stdout: "false", 18 | ExitNum: 1, 19 | }, 20 | { 21 | Block: `os posix`, 22 | Stdout: "true", 23 | }, 24 | } 25 | 26 | test.RunMurexTests(tests, t) 27 | } 28 | -------------------------------------------------------------------------------- /builtins/core/system/system_windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package system_test 5 | 6 | import ( 7 | "testing" 8 | 9 | _ "github.com/lmorg/murex/builtins" 10 | "github.com/lmorg/murex/test" 11 | ) 12 | 13 | func TestOsUnix(t *testing.T) { 14 | tests := []test.MurexTest{ 15 | { 16 | Block: `os windows`, 17 | Stdout: "true", 18 | }, 19 | { 20 | Block: `os posix`, 21 | Stdout: "false", 22 | ExitNum: 1, 23 | }, 24 | } 25 | 26 | test.RunMurexTests(tests, t) 27 | } 28 | -------------------------------------------------------------------------------- /builtins/core/tabulate/tabulate_test.go: -------------------------------------------------------------------------------- 1 | package tabulate 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang/types" 7 | "github.com/lmorg/murex/test" 8 | "github.com/lmorg/murex/utils/json" 9 | ) 10 | 11 | func TestTabulateHelp(t *testing.T) { 12 | b, err := json.Marshal(desc, false) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | 17 | test.RunMethodTest(t, 18 | cmdTabulate, "tabulate", 19 | "", 20 | types.Generic, 21 | []string{"--help"}, 22 | string(b), 23 | nil, 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /builtins/core/tabulate/writer.go: -------------------------------------------------------------------------------- 1 | package tabulate 2 | 3 | type writer interface { 4 | Write([]string) error 5 | Flush() 6 | Error() error 7 | } 8 | -------------------------------------------------------------------------------- /builtins/core/test/state.go: -------------------------------------------------------------------------------- 1 | package cmdtest 2 | 3 | import "github.com/lmorg/murex/lang" 4 | 5 | func testState(p *lang.Process) error { 6 | name, err := p.Parameters.String(1) 7 | if err != nil { 8 | return errUsage("", err) 9 | } 10 | 11 | block, err := p.Parameters.Block(2) 12 | if err != nil { 13 | return errUsage("", err) 14 | } 15 | 16 | return p.Tests.State(name, block) 17 | } 18 | -------------------------------------------------------------------------------- /builtins/core/time/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `misc` 2 | 3 | Some core time based builtins. 4 | 5 | # Package `time` 6 | 7 | This provides some core time based builtins. It contains the following commands: 8 | 9 | * `time` 10 | -------------------------------------------------------------------------------- /builtins/core/time/godoc.go: -------------------------------------------------------------------------------- 1 | // Package time provides some core time based builtins 2 | package time 3 | -------------------------------------------------------------------------------- /builtins/core/typemgmt/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `typemgmt` 2 | 3 | ## Required! 4 | 5 | This package is required as it's used by the shell for managing function 6 | types. -------------------------------------------------------------------------------- /builtins/core/typemgmt/godoc.go: -------------------------------------------------------------------------------- 1 | // Package typemgmt provides core functions for managing murex types and variables 2 | package typemgmt 3 | -------------------------------------------------------------------------------- /builtins/core/vis/godoc.go: -------------------------------------------------------------------------------- 1 | // Package vis provides the visualisation, `vis`, builtin 2 | package vis 3 | -------------------------------------------------------------------------------- /builtins/core/vis/vis.go: -------------------------------------------------------------------------------- 1 | package vis 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/types" 6 | ) 7 | 8 | func init() { 9 | lang.DefineMethod("vis", vis, types.Any, types.Generic) 10 | } 11 | 12 | func vis(p *lang.Process) error { 13 | p.Stdout.SetDataType(types.Generic) 14 | 15 | return tree(p) 16 | } 17 | 18 | func tree(p *lang.Process) error { 19 | //stdio. 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /builtins/docs/docs_test.go: -------------------------------------------------------------------------------- 1 | package docs_test 2 | 3 | import ( 4 | "embed" 5 | "testing" 6 | 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | //go:embed *.go 11 | var docs embed.FS 12 | 13 | // TestSummaries tests the docs directory has been populated with summaries. 14 | // All other files are tested from the builtins/docs_test.go to avoid 15 | // cyclic package import paths 16 | func TestSummaries(t *testing.T) { 17 | test.ExistsFs(t, "summaries.go", docs) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/events/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `event` 2 | 3 | A rudimentary event system for murex -------------------------------------------------------------------------------- /builtins/events/godoc.go: -------------------------------------------------------------------------------- 1 | // Package events provides a basic event framework for murex 2 | package events 3 | -------------------------------------------------------------------------------- /builtins/events/keys.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func CompileInterruptKey(interrupt, name string) string { 9 | return fmt.Sprintf("%s.%s", name, interrupt) 10 | } 11 | 12 | type Key struct { 13 | Name string 14 | Interrupt string 15 | } 16 | 17 | // GetInterruptFromKey returns: name, interrupt 18 | func GetInterruptFromKey(key string) *Key { 19 | split := strings.SplitN(key, ".", 2) 20 | switch len(split) { 21 | case 2: 22 | return &Key{split[0], split[1]} 23 | case 1: 24 | return &Key{split[0], ""} 25 | default: 26 | return &Key{"", ""} 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /builtins/events/onFileSystemChange/filesystem_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | // This isn't currently supported on js/wasm. 5 | 6 | package onfilesystemchange 7 | -------------------------------------------------------------------------------- /builtins/events/onFileSystemChange/filesystem_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | // This isn't currently supported on Plan 9. 5 | 6 | package onfilesystemchange 7 | -------------------------------------------------------------------------------- /builtins/events/onFileSystemChange/filesystem_test.go: -------------------------------------------------------------------------------- 1 | package onfilesystemchange_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/lang/expressions" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | // https://github.com/lmorg/murex/issues/418 11 | func TestIssue418(t *testing.T) { 12 | tests := []test.MurexTest{ 13 | { 14 | Block: `event onFileSystemChange foobar= {}`, 15 | Stderr: `no path to watch supplied`, 16 | ExitNum: 1, 17 | }, 18 | } 19 | 20 | test.RunMurexTestsRx(tests, t) 21 | } 22 | -------------------------------------------------------------------------------- /builtins/events/onFileSystemChange/filesystem_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | // This isn't currently supported on Windows. 5 | // 6 | // It probably wouldn't be a big job to port to Windows but I wouldn't be able 7 | // to test the code works so I think it's better to disable the feature entirely 8 | // rather than ship a broken builtin. 9 | 10 | package onfilesystemchange 11 | -------------------------------------------------------------------------------- /builtins/events/onPreview/onpreview_release.go: -------------------------------------------------------------------------------- 1 | //go:build !trace 2 | // +build !trace 3 | 4 | package onpreview 5 | 6 | func isValidInterruptDebug(_ string) {} 7 | -------------------------------------------------------------------------------- /builtins/events/onPreview/onpreview_trace.go: -------------------------------------------------------------------------------- 1 | //go:build trace 2 | // +build trace 3 | 4 | package onpreview 5 | 6 | func isValidInterruptDebug(interrupt string) { 7 | if err := isValidInterrupt(interrupt); err != nil { 8 | panic(err.Error()) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /builtins/events/onPreview/preview_interrupts.go: -------------------------------------------------------------------------------- 1 | package onpreview 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | ops "github.com/lmorg/murex/builtins/events/onPreview/previewops" 8 | ) 9 | 10 | var interrupts = []string{ 11 | ops.Begin, 12 | ops.End, 13 | ops.Function, 14 | ops.Builtin, 15 | ops.Exec, 16 | } 17 | 18 | func isValidInterrupt(interrupt string) error { 19 | for i := range interrupts { 20 | if interrupts[i] == interrupt { 21 | return nil 22 | } 23 | } 24 | 25 | return fmt.Errorf("invalid interrupt. Expecting one of the following: %s", strings.Join(interrupts, ", ")) 26 | } 27 | -------------------------------------------------------------------------------- /builtins/events/onPreview/previewops/interrupt_operations.go: -------------------------------------------------------------------------------- 1 | package previewops 2 | 3 | const ( 4 | Begin = "start" 5 | End = "end" 6 | Function = "function" 7 | Builtin = "builtin" 8 | Exec = "exec" 9 | ) 10 | -------------------------------------------------------------------------------- /builtins/events/onPrompt/onprompt_release.go: -------------------------------------------------------------------------------- 1 | //go:build !trace 2 | // +build !trace 3 | 4 | package onprompt 5 | 6 | func isValidInterruptDebug(_ string) {} 7 | -------------------------------------------------------------------------------- /builtins/events/onPrompt/onprompt_trace.go: -------------------------------------------------------------------------------- 1 | //go:build trace 2 | // +build trace 3 | 4 | package onprompt 5 | 6 | func isValidInterruptDebug(interrupt string) { 7 | if err := isValidInterrupt(interrupt); err != nil { 8 | panic(err.Error()) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /builtins/events/onPrompt/prompt_interrupts.go: -------------------------------------------------------------------------------- 1 | package onprompt 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | ops "github.com/lmorg/murex/builtins/events/onPrompt/promptops" 8 | ) 9 | 10 | var interrupts = []string{ 11 | ops.Before, 12 | ops.Return, 13 | ops.After, 14 | ops.EOF, 15 | ops.Cancel, 16 | } 17 | 18 | func isValidInterrupt(interrupt string) error { 19 | for i := range interrupts { 20 | if interrupts[i] == interrupt { 21 | return nil 22 | } 23 | } 24 | 25 | return fmt.Errorf("invalid interrupt. Expecting one of the following: %s", strings.Join(interrupts, ", ")) 26 | } 27 | -------------------------------------------------------------------------------- /builtins/events/onPrompt/promptops/interrupt_operations.go: -------------------------------------------------------------------------------- 1 | package promptops 2 | 3 | const ( 4 | Before = "before" 5 | Return = "return" 6 | After = "after" 7 | EOF = "eof" 8 | Cancel = "cancel" 9 | ) 10 | -------------------------------------------------------------------------------- /builtins/events/onSignalReceived/interrupts_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package signaltrap 5 | 6 | type syscall string 7 | 8 | func (s syscall) String() string { return "" } 9 | 10 | var interrupts = map[string]syscall{} 11 | -------------------------------------------------------------------------------- /builtins/events/onSignalReceived/interrupts_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package signaltrap 5 | 6 | type syscall string 7 | 8 | func (s syscall) String() string { return "" } 9 | 10 | var interrupts = map[string]syscall{} 11 | -------------------------------------------------------------------------------- /builtins/events/onSignalReceived/register.go: -------------------------------------------------------------------------------- 1 | //go:build !plan9 && !js 2 | // +build !plan9,!js 3 | 4 | package signaltrap 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/signal" 10 | "syscall" 11 | ) 12 | 13 | var signalChan chan os.Signal = make(chan os.Signal, 1) 14 | 15 | func register(sig string) error { 16 | for name := range interrupts { 17 | if name == sig { 18 | signal.Notify(signalChan, interrupts[name]) 19 | return nil 20 | } 21 | } 22 | 23 | return fmt.Errorf("no signal found named '%s'", sig) 24 | } 25 | 26 | func deregister(sig syscall.Signal) { 27 | signal.Reset(sig) 28 | } 29 | -------------------------------------------------------------------------------- /builtins/events/onSignalReceived/signal_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package signaltrap 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/lmorg/murex/lang" 10 | "github.com/lmorg/murex/lang/types" 11 | ) 12 | 13 | func cmdSendSignal(p *lang.Process) error { 14 | if p.Parameters.Len() == 0 { 15 | return autocompleteSignals(p) 16 | } 17 | 18 | p.Stdout.SetDataType(types.Null) 19 | 20 | return fmt.Errorf("`%s` is not supported on WASM", commandName) 21 | } 22 | -------------------------------------------------------------------------------- /builtins/events/onSignalReceived/signal_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package signaltrap 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/lmorg/murex/lang" 10 | "github.com/lmorg/murex/lang/types" 11 | ) 12 | 13 | func cmdSendSignal(p *lang.Process) error { 14 | if p.Parameters.Len() == 0 { 15 | return autocompleteSignals(p) 16 | } 17 | 18 | p.Stdout.SetDataType(types.Null) 19 | 20 | return fmt.Errorf("`%s` is not supported on Plan 9", commandName) 21 | } 22 | -------------------------------------------------------------------------------- /builtins/optional/dummy.go: -------------------------------------------------------------------------------- 1 | package optional 2 | 3 | // dummy file to allow murex to compile even when no optionals are enabled 4 | -------------------------------------------------------------------------------- /builtins/optional/encoders/README.md: -------------------------------------------------------------------------------- 1 | # Package `encoders` 2 | 3 | This provides some handy builtins for encoding and decoding streams in 4 | various different formats. It contains the following commands: 5 | 6 | * `base64` 7 | * `!base64` 8 | * `!bz2` 9 | * `gz` 10 | * `!gz` 11 | -------------------------------------------------------------------------------- /builtins/optional/encoders/bz2_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: "bz2" 2 | Title: >- 3 | `!bz2` 4 | CategoryID: optional 5 | Summary: >- 6 | Decompress a bz2 file 7 | Description: |- 8 | `!bz2` is an optional builtin for decompressing a bz2 stream from stdin. 9 | Usage: |- 10 | ``` 11 | -> !bz2 -> 12 | ``` 13 | Examples: 14 | Detail: |- 15 | Currently there is no support for compressing a stream using bz2. 16 | Synonyms: 17 | - "!bz2" 18 | Related: 19 | - base64 20 | - gz 21 | - escape 22 | - eschtml 23 | - escurl 24 | - esccli 25 | -------------------------------------------------------------------------------- /builtins/optional/encoders/godoc.go: -------------------------------------------------------------------------------- 1 | // Package encoders provides some handy builtins for encoding and decoding streams in various different formats 2 | package encoders 3 | -------------------------------------------------------------------------------- /builtins/optional/encoders/gz_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: "gz" 2 | Title: >- 3 | `gz` 4 | CategoryID: optional 5 | Summary: >- 6 | Compress or decompress a gzip file 7 | Description: |- 8 | An optional builtin for compressing or decompressing a gzip stream from stdin. 9 | Usage: |- 10 | ``` 11 | -> gz -> 12 | 13 | -> !gz -> 14 | ``` 15 | Examples: 16 | Detail: |- 17 | Synonyms: 18 | - "gz" 19 | - "!gz" 20 | Related: 21 | - base64 22 | - bz2 23 | - escape 24 | - eschtml 25 | - escurl 26 | - esccli 27 | -------------------------------------------------------------------------------- /builtins/optional/optional-barcode.go: -------------------------------------------------------------------------------- 1 | //go:build opt_cmd_barcode 2 | // +build opt_cmd_barcode 3 | 4 | package optional 5 | 6 | // This is an optional package that covers some barcode encodings. 7 | // Uses a 3rd party library: github.com/boombuler/barcode 8 | import _ "github.com/lmorg/murex/builtins/optional/qr" // compile optional builtins 9 | -------------------------------------------------------------------------------- /builtins/optional/optional-encoders.go: -------------------------------------------------------------------------------- 1 | //go:build windows || opt_cmd_encoders 2 | // +build windows opt_cmd_encoders 3 | 4 | package optional 5 | 6 | import ( 7 | _ "github.com/lmorg/murex/builtins/optional/encoders" // base64, file archives, etc 8 | ) 9 | -------------------------------------------------------------------------------- /builtins/optional/optional-printf.go: -------------------------------------------------------------------------------- 1 | //go:build opt_cmd_printf 2 | // +build opt_cmd_printf 3 | 4 | package optional 5 | 6 | import ( 7 | _ "github.com/lmorg/murex/builtins/optional/printf" 8 | ) 9 | -------------------------------------------------------------------------------- /builtins/optional/optional-select.go: -------------------------------------------------------------------------------- 1 | //go:build !no_cmd_select 2 | // +build !no_cmd_select 3 | 4 | package optional 5 | 6 | // This optinal builtin provides SQL inlining via the `select` command. 7 | // It uses sqlite3 as a backend, which will be compiled into the murex executable. 8 | 9 | import _ "github.com/lmorg/murex/builtins/optional/select" // compile optional builtin 10 | -------------------------------------------------------------------------------- /builtins/optional/optional-time.go: -------------------------------------------------------------------------------- 1 | //go:build windows || opt_cmd_time 2 | // +build windows opt_cmd_time 3 | 4 | package optional 5 | 6 | import ( 7 | _ "github.com/lmorg/murex/builtins/optional/time" // sleep 8 | ) 9 | -------------------------------------------------------------------------------- /builtins/optional/pipe-mail.go: -------------------------------------------------------------------------------- 1 | //go:build opt_pipe_mail 2 | // +build opt_pipe_mail 3 | 4 | package optional 5 | 6 | // This is an optional builtin because it duplicates sendmail functionality, 7 | // but it's a handy pipe to have if you wish to send emails from the command 8 | // line using idiomatic murex syntax and controls 9 | 10 | import _ "github.com/lmorg/murex/builtins/pipes/mail" // piping data via esmail 11 | -------------------------------------------------------------------------------- /builtins/optional/pipe-net.go: -------------------------------------------------------------------------------- 1 | //go:build no_pipe_net 2 | // +build no_pipe_net 3 | 4 | package optional 5 | 6 | import _ "github.com/lmorg/murex/builtins/pipes/net" // piping data via IP 7 | -------------------------------------------------------------------------------- /builtins/optional/qr/README.md: -------------------------------------------------------------------------------- 1 | # Package `qrimage` 2 | 3 | This generates a QR code image. It contains the following commands: 4 | 5 | * `qr` 6 | 7 | It has the following additional dependencies: 8 | 9 | go get -u github.com/boombuler/barcode 10 | go get -u github.com/boombuler/barcode/qr 11 | go get -u golang.org/x/image/bmp 12 | go get -u golang.org/x/image/tiff 13 | go get -u golang.org/x/image/webp 14 | 15 | However these are included in the `vendor` directory. 16 | -------------------------------------------------------------------------------- /builtins/optional/qr/godoc.go: -------------------------------------------------------------------------------- 1 | // Package qrimage generates a QR code image 2 | package qrimage 3 | -------------------------------------------------------------------------------- /builtins/optional/select/godoc.go: -------------------------------------------------------------------------------- 1 | // Package sqlselect provides the SELECT builtin for working with tables in sqlite3 2 | package sqlselect 3 | -------------------------------------------------------------------------------- /builtins/optional/select/lib_go.go: -------------------------------------------------------------------------------- 1 | //go:build no_cgo || linux || (windows && amd64) || darwin 2 | // +build no_cgo linux windows,amd64 darwin 3 | 4 | /* 5 | This file uses a pure Go driver for sqlite. Unlike lib_c.go, this one does 6 | not require cgo. For this reason it is the default option for custom builds 7 | however any pre-built binaries on Murex's website will be compiled against 8 | the C driver for sqlite. 9 | */ 10 | 11 | package sqlselect 12 | 13 | import ( 14 | _ "modernc.org/sqlite" 15 | ) 16 | 17 | const driverName = "sqlite" 18 | -------------------------------------------------------------------------------- /builtins/optional/standard-opts.txt: -------------------------------------------------------------------------------- 1 | opt_type_hcl,opt_cmd_barcode -------------------------------------------------------------------------------- /builtins/optional/time/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: `misc` 2 | 3 | Some optional time based builtins. 4 | 5 | # Package `time` 6 | 7 | This provides some optional time based builtins. It contains the following commands: 8 | 9 | * `sleep` 10 | * `time` 11 | -------------------------------------------------------------------------------- /builtins/optional/time/godoc.go: -------------------------------------------------------------------------------- 1 | // Package time provides some optional time based builtins 2 | package time 3 | -------------------------------------------------------------------------------- /builtins/optional/type-hcl.go: -------------------------------------------------------------------------------- 1 | //go:build opt_type_hcl 2 | // +build opt_type_hcl 3 | 4 | package optional 5 | 6 | // Uses a 3rd party library: github.com/hashicorp/hcl 7 | // (included in vendor directory) 8 | import _ "github.com/lmorg/murex/builtins/types/hcl" // compile data type 9 | -------------------------------------------------------------------------------- /builtins/optional/type-sexp.go: -------------------------------------------------------------------------------- 1 | //go:build no_type_sexp 2 | // +build no_type_sexp 3 | 4 | package optional 5 | 6 | // This is an optional builtin for S-Expressions support. 7 | // Uses a 3rd party library: github.com/abesto/sexp 8 | // (included in vendor directory) 9 | import _ "github.com/lmorg/murex/builtins/types/sexp" // compile data type 10 | -------------------------------------------------------------------------------- /builtins/optional/wasm-opts.txt: -------------------------------------------------------------------------------- 1 | opt_cmd_printf,no_cmd_select,opt_cmd_time,no_pipe_net,no_type_sexp,no_pty -------------------------------------------------------------------------------- /builtins/pipes/file/neg_panic.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import "github.com/lmorg/murex/debug" 4 | 5 | var panicOnNegDeps = func(i int32) { 6 | if i < 0 && debug.Enabled { 7 | panic("More closed dependents than open") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/file/neg_panic_test.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | func init() { 4 | panicOnNegDeps = func(i int32) { 5 | if i < 0 { 6 | panic("more closed dependents than open") 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/mail/godoc.go: -------------------------------------------------------------------------------- 1 | // Package mail provides basic email sending capabilities 2 | package mail 3 | -------------------------------------------------------------------------------- /builtins/pipes/net/neg_panic.go: -------------------------------------------------------------------------------- 1 | package net 2 | 3 | import "github.com/lmorg/murex/debug" 4 | 5 | var panicOnNegDeps = func(i int32) { 6 | if i < 0 && debug.Enabled { 7 | panic("More closed dependents than open") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/net/neg_panic_test.go: -------------------------------------------------------------------------------- 1 | package net 2 | 3 | func init() { 4 | panicOnNegDeps = func(i int32) { 5 | if i < 0 { 6 | panic("more closed dependents than open") 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/null/godoc.go: -------------------------------------------------------------------------------- 1 | // Package null provides the null interface (akin to /dev/null). It is REQUIRED by murex! 2 | package null 3 | -------------------------------------------------------------------------------- /builtins/pipes/psuedotty/neg_panic.go: -------------------------------------------------------------------------------- 1 | package psuedotty 2 | 3 | import "github.com/lmorg/murex/debug" 4 | 5 | var panicOnNegDeps = func(i int32) { 6 | if i < 0 && debug.Enabled { 7 | panic("More closed dependents than open") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/psuedotty/neg_panic_test.go: -------------------------------------------------------------------------------- 1 | package psuedotty 2 | 3 | func init() { 4 | panicOnNegDeps = func(i int32) { 5 | if i < 0 { 6 | panic("more closed dependents than open") 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/psuedotty/pty_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build windows || js || plan9 || no_pty 2 | // +build windows js plan9 no_pty 3 | 4 | package psuedotty 5 | 6 | import ( 7 | "github.com/lmorg/murex/builtins/pipes/streams" 8 | "github.com/lmorg/murex/lang/stdio" 9 | ) 10 | 11 | func init() { 12 | stdio.RegisterPipe("pty", registerPipe) 13 | } 14 | 15 | func registerPipe(_ string) (stdio.Io, error) { 16 | return streams.NewStdin(), nil 17 | } 18 | 19 | type PTY struct { 20 | streams.Stdin 21 | } 22 | 23 | func NewPTY(width, height int) (*PTY, error) { 24 | pty := PTY{*streams.NewStdin()} 25 | return &pty, nil 26 | } 27 | -------------------------------------------------------------------------------- /builtins/pipes/psuedotty/teepty.go: -------------------------------------------------------------------------------- 1 | package psuedotty 2 | 3 | import ( 4 | "github.com/lmorg/murex/builtins/pipes/streams" 5 | ) 6 | 7 | func NewTeePTY(width int, height int) (pty *PTY, primary *streams.Tee, secondary *streams.Stdin, err error) { 8 | pty, err = NewPTY(width, height) 9 | if err != nil { 10 | return nil, nil, nil, err 11 | } 12 | 13 | primary, secondary = streams.NewTee(pty) 14 | 15 | return pty, primary, secondary, nil 16 | } 17 | -------------------------------------------------------------------------------- /builtins/pipes/streams/godoc.go: -------------------------------------------------------------------------------- 1 | // Package streams provides the standard streams used by murex and thus is REQUIRED by murex. 2 | package streams 3 | -------------------------------------------------------------------------------- /builtins/pipes/streams/neg_panic.go: -------------------------------------------------------------------------------- 1 | package streams 2 | 3 | import "github.com/lmorg/murex/debug" 4 | 5 | var panicOnNegDeps = func(i int32) { 6 | if i < 0 && debug.Enabled { 7 | panic("More closed dependents than open") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/streams/neg_panic_test.go: -------------------------------------------------------------------------------- 1 | package streams 2 | 3 | func init() { 4 | panicOnNegDeps = func(i int32) { 5 | if i < 0 { 6 | panic("more closed dependents than open") 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /builtins/pipes/term/godoc.go: -------------------------------------------------------------------------------- 1 | // Package term provides the TTY STDOUT and STDERR interfaces. It is REQUIRED by murex! 2 | package term 3 | -------------------------------------------------------------------------------- /builtins/pipes/term/term_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package term 5 | 6 | import ( 7 | "os" 8 | "sync" 9 | "syscall/js" 10 | 11 | "github.com/lmorg/murex/utils/readline" 12 | ) 13 | 14 | var divMutex sync.Mutex 15 | 16 | func vtermWrite(r []rune) { 17 | readline.VTerm.Write(r) 18 | 19 | html := readline.VTerm.ExportHtml() 20 | 21 | divMutex.Lock() 22 | 23 | jsDoc := js.Global().Get("document") 24 | outElement := jsDoc.Call("getElementById", "term") 25 | outElement.Set("innerHTML", html) 26 | 27 | divMutex.Unlock() 28 | } 29 | 30 | func (t *term) File() *os.File { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /builtins/pipes/term/utils.go: -------------------------------------------------------------------------------- 1 | package term 2 | 3 | // Shamelessly stolen from https://blog.golang.org/go-slices-usage-and-internals 4 | // (it works well so why reinvent the wheel?) 5 | func appendBytes(slice []byte, data ...byte) []byte { 6 | m := len(slice) 7 | n := m + len(data) 8 | if n > cap(slice) { // if necessary, reallocate 9 | // allocate double what's needed, for future growth. 10 | newSlice := make([]byte, (n+1)*2) 11 | copy(newSlice, slice) 12 | slice = newSlice 13 | } 14 | slice = slice[0:n] 15 | copy(slice[m:n], data) 16 | return slice 17 | } 18 | -------------------------------------------------------------------------------- /builtins/types/apachelogs/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: apachelogs 2 | 3 | This provides support for reading Apache httpd logs. 4 | 5 | It is an optional builtin and has an additional dependency: 6 | 7 | go get -u github.com/lmorg/murex -------------------------------------------------------------------------------- /builtins/types/apachelogs/godoc.go: -------------------------------------------------------------------------------- 1 | // Package apachelogs provides definitions for the `commonlog` and `errorlog` data types 2 | package apachelogs 3 | -------------------------------------------------------------------------------- /builtins/types/apachelogs/index.go: -------------------------------------------------------------------------------- 1 | package apachelogs 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/utils/json" 6 | ) 7 | 8 | func index(p *lang.Process, params []string) error { 9 | jInterface, err := unmarshal(p) 10 | if err != nil { 11 | return err 12 | } 13 | 14 | marshaller := func(iface interface{}) ([]byte, error) { 15 | return json.Marshal(iface, p.Stdout.IsTTY()) 16 | } 17 | 18 | return lang.IndexTemplateObject(p, params, &jInterface, marshaller) 19 | } 20 | -------------------------------------------------------------------------------- /builtins/types/apachelogs/marshal.go: -------------------------------------------------------------------------------- 1 | package apachelogs 2 | 3 | import ( 4 | "github.com/lmorg/apachelogs" 5 | "github.com/lmorg/murex/lang" 6 | ) 7 | 8 | func unmarshal(p *lang.Process) (interface{}, error) { 9 | var log []apachelogs.AccessLine 10 | 11 | p.Stdin.ReadLine(func(b []byte) { 12 | line, err, _ := apachelogs.ParseAccessLine(string(b)) 13 | if err != nil { 14 | return 15 | } 16 | 17 | log = append(log, *line) 18 | }) 19 | 20 | return log, nil 21 | } 22 | -------------------------------------------------------------------------------- /builtins/types/boolean/boolean_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: bool 2 | Title: >- 3 | `bool` 4 | CategoryID: types 5 | Summary: >- 6 | Boolean (primitive) 7 | Description: |- 8 | A true or false value. 9 | Usage: 10 | Examples: 11 | Hooks: 12 | Marshal(): Supported 13 | Unmarshal(): Supported 14 | Detail: 15 | Associations: 16 | Related: 17 | - str 18 | - num 19 | -------------------------------------------------------------------------------- /builtins/types/boolean/godoc.go: -------------------------------------------------------------------------------- 1 | // Package boolean provides definitions for the boolean data types 2 | package boolean 3 | -------------------------------------------------------------------------------- /builtins/types/boolean/init.go: -------------------------------------------------------------------------------- 1 | package boolean 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/types" 6 | ) 7 | 8 | func init() { 9 | // Register data types 10 | lang.Marshallers[types.Boolean] = marshal 11 | lang.Unmarshallers[types.Boolean] = unmarshal 12 | } 13 | -------------------------------------------------------------------------------- /builtins/types/columns/columns.go: -------------------------------------------------------------------------------- 1 | package columns 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/types" 6 | ) 7 | 8 | func init() { 9 | lang.Marshallers[types.Columns] = marshal 10 | } 11 | -------------------------------------------------------------------------------- /builtins/types/columns/godoc.go: -------------------------------------------------------------------------------- 1 | // Package columns provides definitions for the column, `column`, data type 2 | package columns 3 | -------------------------------------------------------------------------------- /builtins/types/csv-bad/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: csv-bad 2 | 3 | This provides support for non-standard CSV files. 4 | 5 | It is an optional builtin but is recommended to leave enabled. -------------------------------------------------------------------------------- /builtins/types/csv-bad/godoc.go: -------------------------------------------------------------------------------- 1 | // Package csvbad provides definitions for the `csv-bad` data type 2 | package csvbad 3 | -------------------------------------------------------------------------------- /builtins/types/csv/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: CSV 2 | 3 | This provides support for CSV files. 4 | 5 | It is an optional builtin but is recommended to leave enabled. -------------------------------------------------------------------------------- /builtins/types/csv/godoc.go: -------------------------------------------------------------------------------- 1 | // Package csv provides definitions for the `csv` data type 2 | package csv 3 | -------------------------------------------------------------------------------- /builtins/types/example/marshal_test.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang" 7 | "github.com/lmorg/murex/test/count" 8 | ) 9 | 10 | func TestMarshal(t *testing.T) { 11 | count.Tests(t, 1) 12 | 13 | lang.InitEnv() 14 | fork := lang.ShellProcess.Fork(lang.F_NO_STDOUT) 15 | 16 | v := map[string]string{ 17 | "Foo": "Bar", 18 | "Bar": "Foo", 19 | } 20 | 21 | b, err := marshal(fork.Process, v) 22 | if err != nil { 23 | t.Error(err) 24 | } 25 | 26 | if string(b) != `{"Bar":"Foo","Foo":"Bar"}` { 27 | t.Error("JSON marshal failed") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /builtins/types/generic/godoc.go: -------------------------------------------------------------------------------- 1 | // Package generic provides definitions for the generic, `*`, data type 2 | package generic 3 | -------------------------------------------------------------------------------- /builtins/types/hcl/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: HCL 2 | 3 | This provides support for HCL data format: https://github.com/hashicorp/hcl 4 | 5 | It is an optional builtin and has an additional dependency: 6 | 7 | go get -u github.com/hashicorp/hcl 8 | 9 | Because the above library doesn't support marshalling and because JSON 10 | is fully compatible with HCL, Murex will default to marshalling HCL 11 | data types as JSON. -------------------------------------------------------------------------------- /builtins/types/hcl/godoc.go: -------------------------------------------------------------------------------- 1 | // Package hcl provides definitions for the `hcl` data type 2 | package hcl 3 | -------------------------------------------------------------------------------- /builtins/types/json/array_read.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/lmorg/murex/lang" 7 | "github.com/lmorg/murex/lang/stdio" 8 | "github.com/lmorg/murex/utils/json" 9 | ) 10 | 11 | func readArray(ctx context.Context, read stdio.Io, callback func([]byte)) error { 12 | // Create a marshaller function to pass to ArrayTemplate 13 | marshaller := func(v interface{}) ([]byte, error) { 14 | return json.Marshal(v, read.IsTTY()) 15 | } 16 | 17 | return lang.ArrayTemplate(ctx, marshaller, json.Unmarshal, read, callback) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/types/json/godoc.go: -------------------------------------------------------------------------------- 1 | // Package json provides definitions for the `json` data type 2 | package json 3 | -------------------------------------------------------------------------------- /builtins/types/json/map.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "github.com/lmorg/murex/config" 5 | "github.com/lmorg/murex/lang" 6 | "github.com/lmorg/murex/lang/stdio" 7 | "github.com/lmorg/murex/lang/types" 8 | "github.com/lmorg/murex/utils/json" 9 | ) 10 | 11 | func readMap(read stdio.Io, _ *config.Config, callback func(*stdio.Map)) error { 12 | // Create a marshaller function to pass to ArrayWithTypeTemplate 13 | marshaller := func(v interface{}) ([]byte, error) { 14 | return json.Marshal(v, read.IsTTY()) 15 | } 16 | 17 | return lang.MapTemplate(types.Json, marshaller, json.Unmarshal, read, callback) 18 | } 19 | -------------------------------------------------------------------------------- /builtins/types/jsonconcat/godoc.go: -------------------------------------------------------------------------------- 1 | // Package jsonconcat provides definitions for the `jsonc` data type 2 | package jsonconcat 3 | -------------------------------------------------------------------------------- /builtins/types/jsonlines/enclosure.go: -------------------------------------------------------------------------------- 1 | package jsonlines 2 | 3 | import "bytes" 4 | 5 | func noQuote(slice []byte) bool { 6 | return !bytes.HasPrefix(slice, []byte{'"'}) || !bytes.HasSuffix(slice, []byte{'"'}) 7 | } 8 | 9 | func noSquare(slice []byte) bool { 10 | return !bytes.HasPrefix(slice, []byte{'['}) || !bytes.HasSuffix(slice, []byte{']'}) 11 | } 12 | 13 | func noCurly(slice []byte) bool { 14 | return !bytes.HasPrefix(slice, []byte{'{'}) || !bytes.HasSuffix(slice, []byte{'}'}) 15 | } 16 | -------------------------------------------------------------------------------- /builtins/types/jsonlines/godoc.go: -------------------------------------------------------------------------------- 1 | // Package jsonlines provides definitions for the `jsonlines` data type 2 | package jsonlines 3 | -------------------------------------------------------------------------------- /builtins/types/jsonlines/map.go: -------------------------------------------------------------------------------- 1 | package jsonlines 2 | -------------------------------------------------------------------------------- /builtins/types/null/array.go: -------------------------------------------------------------------------------- 1 | package null 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang/stdio" 5 | ) 6 | 7 | type arrayWriter struct { 8 | writer stdio.Io 9 | } 10 | 11 | func newArrayWriter(writer stdio.Io) (stdio.ArrayWriter, error) { 12 | w := &arrayWriter{writer: writer} 13 | return w, nil 14 | } 15 | 16 | func (w *arrayWriter) Write(_ []byte) error { 17 | return nil 18 | } 19 | 20 | func (w *arrayWriter) WriteString(_ string) error { 21 | return nil 22 | } 23 | 24 | func (w *arrayWriter) Close() error { return nil } 25 | -------------------------------------------------------------------------------- /builtins/types/null/init.go: -------------------------------------------------------------------------------- 1 | package null 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/stdio" 6 | "github.com/lmorg/murex/lang/types" 7 | ) 8 | 9 | func init() { 10 | // Register data type 11 | lang.Marshallers[types.Null] = marshal 12 | lang.Unmarshallers[types.Null] = unmarshal 13 | stdio.RegisterWriteArray(types.Null, newArrayWriter) 14 | } 15 | -------------------------------------------------------------------------------- /builtins/types/null/null_test.go: -------------------------------------------------------------------------------- 1 | package null 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang/types" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestArrayWriter(t *testing.T) { 11 | input := []string{"foo", "bar"} 12 | test.ArrayWriterTest(t, types.Null, input, "") 13 | } 14 | -------------------------------------------------------------------------------- /builtins/types/numeric/godoc.go: -------------------------------------------------------------------------------- 1 | // Package numeric provides definitions for numeric data types (int, float, num) 2 | package numeric 3 | -------------------------------------------------------------------------------- /builtins/types/numeric/init.go: -------------------------------------------------------------------------------- 1 | package numeric 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/types" 6 | ) 7 | 8 | func init() { 9 | // Register data types 10 | lang.Marshallers[types.Integer] = marshalInt 11 | lang.Unmarshallers[types.Integer] = unmarshalInt 12 | 13 | lang.Marshallers[types.Float] = marshalFloat 14 | lang.Unmarshallers[types.Float] = unmarshalFloat 15 | 16 | lang.Marshallers[types.Number] = marshalNumber 17 | lang.Unmarshallers[types.Number] = unmarshalNumber 18 | } 19 | -------------------------------------------------------------------------------- /builtins/types/paths/godoc.go: -------------------------------------------------------------------------------- 1 | // Package paths provides definitions for the `path` and `paths` data types 2 | package paths 3 | -------------------------------------------------------------------------------- /builtins/types/paths/separator_unix.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package paths 5 | 6 | var pathsSeparator = []byte{':'} 7 | -------------------------------------------------------------------------------- /builtins/types/paths/separator_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package paths 5 | 6 | var pathsSeparator = []byte{';'} 7 | -------------------------------------------------------------------------------- /builtins/types/querystring/godoc.go: -------------------------------------------------------------------------------- 1 | // Package string provides definitions for the `str` data type 2 | package string 3 | -------------------------------------------------------------------------------- /builtins/types/querystring/querystring.go: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang" 5 | "github.com/lmorg/murex/lang/stdio" 6 | ) 7 | 8 | const dataType = "qs" 9 | 10 | func init() { 11 | // Register data type 12 | lang.Marshallers[dataType] = marshal 13 | lang.Unmarshallers[dataType] = unmarshal 14 | lang.ReadIndexes[dataType] = index 15 | 16 | stdio.RegisterReadArray(dataType, readArray) 17 | stdio.RegisterReadArrayWithType(dataType, readArrayWithType) 18 | stdio.RegisterReadMap(dataType, readMap) 19 | } 20 | -------------------------------------------------------------------------------- /builtins/types/sexp/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: S-Expressions 2 | 3 | This provides support for S-Expressions. 4 | 5 | It is an optional builtin and has an additional dependency: 6 | 7 | go get -u github.com/abesto/sexp -------------------------------------------------------------------------------- /builtins/types/sexp/godoc.go: -------------------------------------------------------------------------------- 1 | // Package sexp provides definitions for the S-Expression data types: `sexpr` and `csexp` 2 | package sexp 3 | -------------------------------------------------------------------------------- /builtins/types/string/array_write.go: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import ( 4 | "github.com/lmorg/murex/lang/stdio" 5 | ) 6 | 7 | type arrayWriter struct { 8 | writer stdio.Io 9 | } 10 | 11 | func newArrayWriter(writer stdio.Io) (stdio.ArrayWriter, error) { 12 | w := &arrayWriter{writer: writer} 13 | return w, nil 14 | } 15 | 16 | func (w *arrayWriter) Write(b []byte) error { 17 | _, err := w.writer.Writeln(b) 18 | return err 19 | } 20 | 21 | func (w *arrayWriter) WriteString(s string) error { 22 | _, err := w.writer.Writeln([]byte(s)) 23 | return err 24 | } 25 | 26 | func (w *arrayWriter) Close() error { return nil } 27 | -------------------------------------------------------------------------------- /builtins/types/string/godoc.go: -------------------------------------------------------------------------------- 1 | // Package string provides definitions for the `str` data type 2 | package string 3 | -------------------------------------------------------------------------------- /builtins/types/toml/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: TOML 2 | 3 | This provides support for TOML data format. 4 | 5 | It is an optional builtin and has an additional dependency: 6 | 7 | go get -u github.com/BurntSushi/toml -------------------------------------------------------------------------------- /builtins/types/toml/array_read.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/lmorg/murex/lang" 7 | "github.com/lmorg/murex/lang/stdio" 8 | "github.com/pelletier/go-toml" 9 | ) 10 | 11 | func readArray(ctx context.Context, read stdio.Io, callback func([]byte)) error { 12 | return lang.ArrayTemplate(ctx, toml.Marshal, toml.Unmarshal, read, callback) 13 | } 14 | 15 | func readArrayWithType(ctx context.Context, read stdio.Io, callback func(interface{}, string)) error { 16 | return lang.ArrayWithTypeTemplate(ctx, typeName, toml.Marshal, toml.Unmarshal, read, callback) 17 | } 18 | -------------------------------------------------------------------------------- /builtins/types/toml/godoc.go: -------------------------------------------------------------------------------- 1 | // Package toml provides definitions for the `toml` data type 2 | package toml 3 | -------------------------------------------------------------------------------- /builtins/types/toml/map.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import ( 4 | "github.com/lmorg/murex/config" 5 | "github.com/lmorg/murex/lang" 6 | "github.com/lmorg/murex/lang/stdio" 7 | toml "github.com/pelletier/go-toml" 8 | ) 9 | 10 | func readMap(read stdio.Io, _ *config.Config, callback func(*stdio.Map)) error { 11 | return lang.MapTemplate(typeName, toml.Marshal, toml.Unmarshal, read, callback) 12 | } 13 | -------------------------------------------------------------------------------- /builtins/types/yaml/README.md: -------------------------------------------------------------------------------- 1 | # Builtins: YAML 2 | 3 | This provides support for YAML data format. 4 | 5 | It is an optional builtin and has an additional dependency: 6 | 7 | go get -u gopkg.in/yaml.v2 -------------------------------------------------------------------------------- /builtins/types/yaml/godoc.go: -------------------------------------------------------------------------------- 1 | // Package yaml provides definitions for the `yaml` data type 2 | package yaml 3 | -------------------------------------------------------------------------------- /config/defaults/godoc.go: -------------------------------------------------------------------------------- 1 | // Package defaults defines the default state for many run time config 2 | package defaults 3 | -------------------------------------------------------------------------------- /config/defaults/profile_any.go: -------------------------------------------------------------------------------- 1 | package defaults 2 | 3 | import ( 4 | _ "embed" 5 | ) 6 | 7 | //go:embed profile_any.mx 8 | var profileAny []byte 9 | 10 | func init() { 11 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 12 | Name: "profile_any", 13 | Block: profileAny, 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /config/defaults/profile_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | // +build darwin 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_darwin.mx 11 | var profileDarwin []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_darwin", 16 | Block: profileDarwin, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_darwin.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_darwin.mx -------------------------------------------------------------------------------- /config/defaults/profile_dragonfly.go: -------------------------------------------------------------------------------- 1 | //go:build dragonfly 2 | // +build dragonfly 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_dragonfly.mx 11 | var profileDragonfly []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_dragonfly", 16 | Block: profileDragonfly, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_dragonfly.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_dragonfly.mx -------------------------------------------------------------------------------- /config/defaults/profile_freebsd.go: -------------------------------------------------------------------------------- 1 | //go:build freebsd 2 | // +build freebsd 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_freebsd.mx 11 | var profileFreebsd []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_freebsd", 16 | Block: profileFreebsd, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_freebsd.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_freebsd.mx -------------------------------------------------------------------------------- /config/defaults/profile_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_linux.mx 11 | var profileLinux []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_linux", 16 | Block: profileLinux, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_netbsd.go: -------------------------------------------------------------------------------- 1 | //go:build netbsd 2 | // +build netbsd 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_netbsd.mx 11 | var profileNetbsd []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_netbsd", 16 | Block: profileNetbsd, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_netbsd.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_netbsd.mx -------------------------------------------------------------------------------- /config/defaults/profile_openbsd.go: -------------------------------------------------------------------------------- 1 | //go:build openbsd 2 | // +build openbsd 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_openbsd.mx 11 | var profileOpenbsd []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_openbsd", 16 | Block: profileOpenbsd, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_openbsd.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_openbsd.mx -------------------------------------------------------------------------------- /config/defaults/profile_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_plan9.mx 11 | var profilePlan9 []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_plan9", 16 | Block: profilePlan9, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_plan9.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_plan9.mx -------------------------------------------------------------------------------- /config/defaults/profile_posix.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && !plan9 2 | // +build !windows,!plan9 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_posix.mx 11 | var profilePosix []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_posix", 16 | Block: profilePosix, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_preload.go: -------------------------------------------------------------------------------- 1 | package defaults 2 | 3 | import ( 4 | _ "embed" 5 | ) 6 | 7 | //go:embed profile_preload.mx 8 | var profilePreload []byte 9 | 10 | func init() { 11 | // push to top of slice so it is first profile loaded 12 | DefaultProfiles = append([]*DefaultProfileT{{ 13 | Name: "profile_preload", 14 | Block: profilePreload, 15 | }}, DefaultProfiles...) 16 | } 17 | -------------------------------------------------------------------------------- /config/defaults/profile_solaris.go: -------------------------------------------------------------------------------- 1 | //go:build solaris 2 | // +build solaris 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_solaris.mx 11 | var profileSolaris []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_solaris", 16 | Block: profileSolaris, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_solaris.mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/config/defaults/profile_solaris.mx -------------------------------------------------------------------------------- /config/defaults/profile_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package defaults 5 | 6 | import ( 7 | _ "embed" 8 | ) 9 | 10 | //go:embed profile_windows.mx 11 | var profileWindows []byte 12 | 13 | func init() { 14 | DefaultProfiles = append(DefaultProfiles, &DefaultProfileT{ 15 | Name: "profile_windows", 16 | Block: profileWindows, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /config/defaults/profile_windows.mx: -------------------------------------------------------------------------------- 1 | autocomplete set cast %[{ 2 | Dynamic: '{ runtime --unmarshallers }' 3 | }] 4 | 5 | autocomplete set tout %[{ 6 | Dynamic: '{ runtime --marshallers }' 7 | }] -------------------------------------------------------------------------------- /config/godoc.go: -------------------------------------------------------------------------------- 1 | // Package config provides APIs for managing the shell's runtime config 2 | package config 3 | -------------------------------------------------------------------------------- /config/profile/godoc.go: -------------------------------------------------------------------------------- 1 | // Package profile is used to read the various non-default murex user profiles and modules 2 | package profile 3 | -------------------------------------------------------------------------------- /config/profile/module_test.mx: -------------------------------------------------------------------------------- 1 | # this just needs to be an empty file for stat'ing -------------------------------------------------------------------------------- /debug/badmutex.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | // BadMutex is only used to test deadlocks and shouldn't be used in release code. 4 | type BadMutex struct{} 5 | 6 | // Lock is a fake mutex lock used to check deadlocks 7 | func (bm *BadMutex) Lock() {} 8 | 9 | // Unlock is a fake mutex Unlock used to check deadlocks 10 | func (bm *BadMutex) Unlock() {} 11 | -------------------------------------------------------------------------------- /debug/godoc.go: -------------------------------------------------------------------------------- 1 | // Package debug provides debugging APIs 2 | package debug 3 | -------------------------------------------------------------------------------- /examples/appsize.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | 3 | $name = "murex" 4 | 5 | try { 6 | ls -lh ${which $name} -> regexp %(f/([0-9.]+[A-Z])/) -> set size 7 | # The above line is equivalent to the follow: 8 | # which $name -> set path 9 | # ls -lh $path -> regexp f/[0-9.]+M/ -> set size 10 | 11 | out "The $name executable is $size big!" 12 | } 13 | catch { 14 | err "`$(name)` not found in \$PATH" 15 | } 16 | -------------------------------------------------------------------------------- /examples/arrays-as-parameters.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | # 3 | # This example uses arrays as parameters 4 | 5 | fruit = %[apples oranges bananas] 6 | out "I have the following fruit in my fruit bowl:" @fruit "," 7 | out "But I mostly love $(fruit.1)." 8 | 9 | /# 10 | Outputs: 11 | 12 | I have the following fruit in my fruit bowl: apples oranges bananas, 13 | But I mostly love oranges. 14 | #/ -------------------------------------------------------------------------------- /examples/dictionary-api.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | 3 | words = list.join('%20' @PARAMS) 4 | 5 | open https://api.dictionaryapi.dev/api/v2/entries/en/$(words) \ 6 | -> foreach { 7 | -> [ meanings ] -> foreach meaning { 8 | -> [ definitions ] -> foreach def { 9 | $definitions <~ %[ { 10 | partOfSpeech: $meaning.partOfSpeech 11 | meaning: $def.definition 12 | } ] 13 | } 14 | } 15 | } 16 | 17 | $definitions -------------------------------------------------------------------------------- /examples/foreach.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | # 3 | # This example demonstrates `foreach` 4 | 5 | %[ 1..5 ] -> foreach i { 6 | echo $i 7 | } 8 | 9 | /# 10 | Outputs: 11 | 12 | 1 13 | 2 14 | 3 15 | 4 16 | 5 17 | #/ -------------------------------------------------------------------------------- /examples/hello-world.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | 3 | out Hello World! 4 | -------------------------------------------------------------------------------- /examples/loops-iteration.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | 3 | # Idiomatic way of iterating in murex 4 | 5 | out "Iteration over a foreach loop:" 6 | 7 | %[0..4] -> foreach i { 8 | out " %[0..4] -> foreach i { $i -> ... }" 9 | } 10 | 11 | 12 | # While loop 13 | 14 | out "Iteration over a while loop:" 15 | 16 | i = 0 17 | while { $i < 5 } { 18 | out " while { $i < 5 } { ... }" 19 | i += 1 20 | } 21 | 22 | 23 | # Traditional for loop 24 | 25 | out "Iteration over a for loop:" 26 | 27 | for ( i=0; i<5; i++ ) { 28 | out " for ( i=0; $i<5; i++ ) { ... }" 29 | } -------------------------------------------------------------------------------- /examples/table-indexes.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | # 3 | # This gets indexes from tabulated data 4 | 5 | ps aux | [PID %CPU COMMAND] | head -n5 6 | 7 | /# 8 | Outputs: 9 | 10 | PID %CPU COMMAND 11 | 77045 127.5 /usr/sbin/netbiosd 12 | 85046 14.9 /Applications/iTerm.app/Contents/MacOS/iTerm2 13 | 371 3.7 /System/Library/PrivateFrameworks/SkyLight.framework/Resources/WindowServer 14 | 4302 3.3 /Applications/Firefox.app/Contents/MacOS/firefox 15 | #/ -------------------------------------------------------------------------------- /examples/try-catch.mx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env murex 2 | 3 | # try / catch 4 | try { out hello world -> grep foobar; out other stuff } 5 | catch { out `catch` successfully caught an error in `try` } 6 | 7 | # catch 8 | out hello world -> grep: foobar 9 | catch { out `catch` spotted that foobar was not found } 10 | 11 | # !catch 12 | out hello world -> grep world; !catch { out world found } 13 | 14 | # else 15 | try { out: hello world -> grep foobar; out other stuff } 16 | catch { out `try` failed } 17 | !catch { out `try` succeeded } 18 | -------------------------------------------------------------------------------- /gen/apis-md-cat.inc.md: -------------------------------------------------------------------------------- 1 | This section is a glossary of APIs. 2 | 3 | These APIs are provided for reference for any developers wishing to write 4 | their own builtins. However some APIs are still worth being aware of even 5 | when just writing Murex scripts because they provide a background into 6 | the internal logic of Murex's runtime. -------------------------------------------------------------------------------- /gen/blog-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | title: {{ .Title }} 3 | description: {{ quote .Summary }} 4 | index: true 5 | icon: comment 6 | category: {{ .Title }} 7 | --- 8 | 9 | {{ end }}# {{ md .Title }}{{ if .Description }} 10 | 11 | {{ md (include .Description) }}{{ end }} 12 | 13 | ## Articles 14 | 15 | {{ if .Documents }}{{ range $i,$a := .DateTime }}{{ if gt $i 0 }} 16 | {{ end }}### {{ date .DateTime }} - [{{ md .Title }}](../{{ md .Hierarchy }}.md) 17 | 18 | > {{ md .Summary }} 19 | 20 | {{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/blog/wasm_electron_future_doc.yaml.unpublished: -------------------------------------------------------------------------------- 1 | - DocumentID: wasm_electron_future 2 | Title: >- 3 | WebAssembly, Electron, And The Future Of $SHELL's 4 | CategoryID: blog 5 | DateTime: 2021-05-06 08:24 6 | Summary: >- 7 | This article discuses the motivation behind creating a new shell 8 | Description: |- 9 | 10 | Synonyms: 11 | Related: 12 | - select 13 | - jsonl 14 | - csv 15 | - generic 16 | - jobs 17 | - fg 18 | - bg 19 | - ReadArrayWithType 20 | - foreach 21 | 22 | -------------------------------------------------------------------------------- /gen/blog/what_makes_a_good_shell_doc.yaml.unpublished: -------------------------------------------------------------------------------- 1 | - DocumentID: what_makes_a_good_shell 2 | Title: >- 3 | What Makes A Good Shell? 4 | CategoryID: blog 5 | DateTime: 2021-05-06 08:24 6 | Summary: >- 7 | This article discuses the motivation behind creating a new shell 8 | Description: |- 9 | 10 | Synonyms: 11 | Related: 12 | - select 13 | - jsonl 14 | - csv 15 | - generic 16 | - jobs 17 | - fg 18 | - bg 19 | - ReadArrayWithType 20 | - foreach 21 | 22 | -------------------------------------------------------------------------------- /gen/blog/whats_in_a_name_doc.yaml.unpublished: -------------------------------------------------------------------------------- 1 | - DocumentID: whats_in_a_name 2 | Title: >- 3 | What's In A Name? 4 | CategoryID: blog 5 | DateTime: 2021-05-06 08:24 6 | Summary: >- 7 | Why Is This Project Named 'Murex'? 8 | Description: |- 9 | 10 | Synonyms: 11 | Related: 12 | - select 13 | - jsonl 14 | - csv 15 | - generic 16 | - jobs 17 | - fg 18 | - bg 19 | - ReadArrayWithType 20 | - foreach 21 | 22 | -------------------------------------------------------------------------------- /gen/blog/why_create_a_new_shell_doc.yaml.unpublished: -------------------------------------------------------------------------------- 1 | - DocumentID: why_create_a_new_shell 2 | Title: >- 3 | Why Create A New Shell? 4 | CategoryID: blog 5 | DateTime: 2021-05-06 08:24 6 | Summary: >- 7 | This article discuses the motivation behind creating a new shell 8 | Description: |- 9 | {{ include "gen/blog/why_create_a_new_shell.inc.md" }} 10 | Synonyms: 11 | Related: 12 | - foreach 13 | - formap 14 | - mkarray 15 | - create-array 16 | - cast 17 | 18 | 19 | -------------------------------------------------------------------------------- /gen/changelog-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | index: true 3 | title: {{ .Title }} 4 | description: {{ quote .Summary }} 5 | icon: laptop-code 6 | category: {{ .Title }} 7 | --- 8 | 9 | {{ end }}# {{ md .Title }}{{ if .Description }} 10 | 11 | {{ md (include .Description) }}{{ end }} 12 | 13 | ## Articles 14 | 15 | {{ if .Documents }}{{ range $i,$a := .DateTime }}{{ if gt $i 0 }} 16 | {{ end }}### {{ date .DateTime }} - [{{ md .Title }}](../{{ md .Hierarchy }}.md) 17 | 18 | {{ md .Summary }} 19 | 20 | {{ end }}{{ else }}No pages currently exist for this category.{{ end }} 21 | -------------------------------------------------------------------------------- /gen/changelog/v5.1_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v5.1 2 | Title: >- 3 | v5.1 4 | CategoryID: changelog 5 | DateTime: 2023-10-09 22:13 6 | Summary: >- 7 | This release brings new operators and a builtin, all for managing null types. 8 | There is also a substantial revamp to readline's responsiveness. 9 | Description: |- 10 | {{ include "gen/changelog/v5.1.inc.md" }} 11 | Related: 12 | - debug -------------------------------------------------------------------------------- /gen/changelog/v5.2_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v5.2 2 | Title: >- 3 | v5.2 4 | CategoryID: changelog 5 | DateTime: 2023-11-18 20:59 6 | Summary: >- 7 | The v5.2 release introduces significant new features and improvements for those 8 | using Murex as their interactive shell. Many of these features are unique to 9 | Murex. 10 | Description: |- 11 | {{ include "gen/changelog/v5.2.inc.md" }} 12 | Related: 13 | - CONTRIBUTING 14 | - job-control 15 | - bg 16 | - fg 17 | - debug 18 | - terminal-keys 19 | - INSTALL 20 | - count 21 | - lambda 22 | -------------------------------------------------------------------------------- /gen/changelog/v5.3_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v5.3 2 | Title: >- 3 | v5.3 4 | CategoryID: changelog 5 | DateTime: 2024-01-02 15:45 6 | Summary: >- 7 | Caching has been vastly improved in this release due to a new sqlite3-backed persistent `cache.db`. There have also been some improvements to `[f1]` help pages 8 | Description: |- 9 | {{ include "gen/changelog/v5.3.inc.md" }} 10 | Related: 11 | - CONTRIBUTING 12 | - autocomplete 13 | - export 14 | - config 15 | - runtime 16 | - is-null 17 | -------------------------------------------------------------------------------- /gen/changelog/v6.0_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v6.0 2 | Title: >- 3 | v6.0 4 | CategoryID: changelog 5 | DateTime: 2024-02-17 20:47 6 | Summary: >- 7 | Despite this being a new major version release, it is a vary minor update. 8 | Aside from a handful of bugfixes, the most significant change is notice of 9 | deprecation for `=`, `let`, and `?`. 10 | Description: |- 11 | {{ include "gen/changelog/v6.0.inc.md" }} 12 | Related: 13 | - CONTRIBUTING 14 | - autocomplete 15 | - export 16 | - config 17 | - runtime 18 | - is-null 19 | -------------------------------------------------------------------------------- /gen/changelog/v6.2_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v6.2 2 | Title: >- 3 | v6.2 4 | CategoryID: changelog 5 | DateTime: 2024-07-19 08:54 6 | Summary: >- 7 | Bug fix release 8 | Description: |- 9 | {{ include "gen/changelog/v6.2.inc.md" }} 10 | Related: 11 | - CONTRIBUTING 12 | - expr 13 | - murex-docs 14 | - murex-package 15 | - chatgpt 16 | - export 17 | - operators-and-tokens 18 | -------------------------------------------------------------------------------- /gen/changelog/v6.4_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: v6.4 2 | Title: >- 3 | v6.4 4 | CategoryID: changelog 5 | DateTime: 2024-12-11 22:09 6 | Summary: >- 7 | This change brings a number of ergonomic improvements to job control, 8 | `datetime` and working with structures. 9 | Description: |- 10 | {{ include "gen/changelog/v6.4.inc.md" }} 11 | Related: 12 | - CONTRIBUTING 13 | - bg 14 | - fg 15 | - datetime 16 | - index 17 | - element 18 | - runtime 19 | - config 20 | - onPrompt 21 | - csv 22 | - expr 23 | - int 24 | -------------------------------------------------------------------------------- /gen/commands-vue-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ vuepressmenu "commands" }} -------------------------------------------------------------------------------- /gen/events-md-cat.inc.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/events-md-cat.inc.md -------------------------------------------------------------------------------- /gen/events-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | index: true 3 | title: {{ .Title }} 4 | description: {{ quote .Summary }} 5 | category: {{ .Title }} 6 | --- 7 | {{ end }}# {{ md .Title }}{{ if .Description }} 8 | 9 | {{ md (include .Description) }}{{ end }} 10 | 11 | ## Pages 12 | 13 | {{ if .Documents }}{{ range $i,$a := .Documents }}{{ if gt $i 0 }} 14 | {{ end }}* [{{ md .Title }}](../{{ md .Hierarchy }}.md): 15 | {{ md .Summary }}{{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/includes/autogenerated.mkarray.inc.md: -------------------------------------------------------------------------------- 1 | * [Calendar Date Ranges](../mkarray/date.md): 2 | Create arrays of dates 3 | * [Character arrays](../mkarray/character.md): 4 | Making character arrays (a to z) 5 | * [Decimal Ranges](../mkarray/decimal.md): 6 | Create arrays of decimal integers 7 | * [Non-Decimal Ranges](../mkarray/non-decimal.md): 8 | Create arrays of integers from non-decimal number bases 9 | * [Special Ranges](../mkarray/special.md): 10 | Create arrays from ranges of dictionary terms (eg weekdays, months, seasons, etc) -------------------------------------------------------------------------------- /gen/includes/c-style-valid-fun.inc.md: -------------------------------------------------------------------------------- 1 | Please note that currently the only functions supported are ones who's names 2 | are comprised entirely of alpha, numeric, underscore and/or exclamation marks. -------------------------------------------------------------------------------- /gen/includes/event-payload-summary.inc.md: -------------------------------------------------------------------------------- 1 | The following payload is passed to the function via stdin: -------------------------------------------------------------------------------- /gen/includes/event-return-summary.inc.md: -------------------------------------------------------------------------------- 1 | `$EVENT_RETURN`, is a special variable that stores a writable structure to 2 | return back to the event caller. 3 | 4 | The `$EVENT_RETURN` values available for this event are: -------------------------------------------------------------------------------- /gen/includes/expr-strict-types-assignment.inc.md: -------------------------------------------------------------------------------- 1 | ### Strict Types 2 | 3 | Unlike with the standard arithmetic operators (`+`, `-`, `*`, `/`), silent data 4 | casting isn't supported with arithmetic assignments like `+=`, `-=`, `*=` and 5 | `/=`. Not even when `strict-types` is disabled ({{link "read more" "strict-types"}}) 6 | 7 | You can work around this by using the slightly longer syntax: **variable = 8 | value op value**, for example: 9 | 10 | ``` 11 | » $i = "3" 12 | » $i = $i + "2" 13 | » $i 14 | 5 15 | ``` -------------------------------------------------------------------------------- /gen/includes/fid-kill.inc.md: -------------------------------------------------------------------------------- 1 | `fid-kill` doesn't send a kernel signal to the process since Murex is 2 | a multi-threaded shell with a single signal, `fid-kill` will send a 3 | cancellation context to any builtins executing (which covers builtins, 4 | aliases, public and private functions and any external executables running 5 | which were launched within the current Murex shell). 6 | 7 | The FID (function ID) sent is not the same as a POSIX (eg Linux, macOS, BSD) 8 | PID (process ID). You can obtain a FID from `fid-list`. -------------------------------------------------------------------------------- /gen/includes/meta-values.inc.md: -------------------------------------------------------------------------------- 1 | ### Meta values 2 | 3 | Meta values are a JSON object stored as the variable `$.`. The meta variable 4 | will get overwritten by any other block which invokes meta values. So if you 5 | wish to persist meta values across blocks you will need to reassign `$.`, eg 6 | 7 | ``` 8 | %[1..3] -> foreach { 9 | meta_parent = $. 10 | %[7..9] -> foreach { 11 | out "$(meta_parent.i): $.i" 12 | } 13 | } 14 | ``` 15 | 16 | The following meta values are defined: -------------------------------------------------------------------------------- /gen/includes/mkarray-range-description.inc.md: -------------------------------------------------------------------------------- 1 | Please refer to [a (mkarray)](../commands/a.md) for more detailed usage of mkarray. -------------------------------------------------------------------------------- /gen/includes/mkarray-range-usage.inc.md: -------------------------------------------------------------------------------- 1 | ``` 2 | a: [start..end] -> 3 | a: [start..end,start..end] -> 4 | a: [start..end][start..end] -> 5 | ``` 6 | 7 | All usages also work with `ja` and `ta` as well, eg: 8 | 9 | ``` 10 | ja: [start..end] -> 11 | ta: data-type [start..end] -> 12 | ``` 13 | 14 | You can also inline arrays with the `%[]` syntax, eg: 15 | 16 | ``` 17 | %[start..end] 18 | ``` -------------------------------------------------------------------------------- /gen/includes/this-is-a-reserved-var.inc.md: -------------------------------------------------------------------------------- 1 | This is a {{link "reserved variable" "reserved-vars"}} so it cannot be changed. 2 | -------------------------------------------------------------------------------- /gen/integrations-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ $doc := doct "" "integrations" }}{{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | index: true 3 | icon: puzzle-piece 4 | title: {{ quote .Title }} 5 | description: {{ quote .Summary }} 6 | category: {{ .Title }} 7 | --- 8 | 9 | {{ end }}# {{ .Title }} 10 | 11 | {{ include $doc.Description }} 12 | -------------------------------------------------------------------------------- /gen/mkarray-inc-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if .Documents }}{{ range $i,$a := .Documents }}{{ if gt $i 0 }} 2 | {{ end }}* [{{ md .Title }}](../{{ md .Hierarchy }}.md): 3 | {{ md .Summary }}{{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/murex-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | index: true 3 | title: {{ md .Title }} 4 | description: {{ quote .Summary }} 5 | category: {{ .Title }} 6 | --- 7 | 8 | {{ end }}# {{ md .Title }}{{ if .Description }} 9 | 10 | {{ md (include .Description) }}{{ end }} 11 | 12 | ## Pages 13 | 14 | {{ if .Documents }}{{ range $i,$a := .Documents }}{{ if gt $i 0 }} 15 | {{ end }}* [{{ md .Title }}](../{{ md .Hierarchy }}.md): 16 | {{ md .Summary }}{{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/parser-md-cat.inc.md: -------------------------------------------------------------------------------- 1 | {{ fn (file "gen/includes/expr-operators-tokens.inc.md") }} 2 | 3 | ## Other Reference Material 4 | 5 | ### Language Guides 6 | 7 | 1. {{link "Language Tour" "tour"}}, which is an introduction into the Murex language. 8 | 9 | 2. {{link "Rosetta Stone" "rosetta-stone"}}, which is a reference table comparing Bash syntax to Murex's. 10 | 11 | 3. {{section "Builtins" "commands" ""}}, for docs on the core builtins. 12 | 13 | ### Murex's Source Code 14 | 15 | The parser is located Murex's source under the `lang/expressions/` path of the project 16 | files. -------------------------------------------------------------------------------- /gen/parser-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ $doc := doct "" "operators-and-tokens" }}{{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | title: {{ $doc.Title }} 3 | description: {{ quote .Summary }} 4 | index: true 5 | category: {{ .Title }} 6 | --- 7 | 8 | {{ end }}# {{ md $doc.Title }}{{ if .Description }} 9 | 10 | {{ md (include .Description) }}{{ end }} 11 | 12 | ## Pages 13 | 14 | {{ if .Documents }}{{ range $i,$a := .Documents }}{{ if gt $i 0 }} 15 | {{ end }}* [{{ md .Title }}](../{{ md .Hierarchy }}.md): 16 | {{ md .Summary }}{{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/parser-vue-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ vuepressmenu "parser" }} -------------------------------------------------------------------------------- /gen/parser/codeblock-nesting.inc.md: -------------------------------------------------------------------------------- 1 | Curly braces can be nested: 2 | 3 | ``` 4 | » out {{foo} bar} 5 | {{foo} bar} 6 | ``` -------------------------------------------------------------------------------- /gen/root-md-doc.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | description: {{ quote .Summary }} 3 | {{ end }}{{ md (include .Description) }}{{ if .Related }} 4 | 5 | ## See Also 6 | 7 | {{ range $i,$a := .Related }}{{ if gt $i 0 }} 8 | {{ end }}* [{{ md .Title }}]({{ if env "DOCGEN_TARGET=" }}{{ md .WriteTo }}/{{ end }}{{ md .ID }}.md): 9 | {{ md .Summary }}{{ end }}{{ end }} 10 | 11 |
12 | 13 | This document was generated from [{{ .SourcePath }}](https://github.com/lmorg/murex/blob/master/{{ .SourcePath }}). -------------------------------------------------------------------------------- /gen/root/CONTRIBUTING_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: CONTRIBUTING 2 | Title: >- 3 | How To Contribute 4 | CategoryID: Murex 5 | Summary: >- 6 | Murex is community project. We gratefully accept contributions 7 | Description: |- 8 | {{ include "gen/root/CONTRIBUTING.inc.md" }} 9 | Synonyms: 10 | Related: 11 | - compatibility 12 | -------------------------------------------------------------------------------- /gen/root/DOWNLOAD_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: DOWNLOAD 2 | Title: >- 3 | Download Links 4 | CategoryID: Murex 5 | Summary: >- 6 | Murex download links 7 | Description: |- 8 | {{ include "gen/root/DOWNLOAD.inc.md" }} 9 | Synonyms: 10 | Related: 11 | - INSTALL 12 | - supported-platforms 13 | - compatibility 14 | -------------------------------------------------------------------------------- /gen/root/INSTALL_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: INSTALL 2 | Title: >- 3 | Install 4 | CategoryID: Murex 5 | Summary: >- 6 | Installation Instructions 7 | Description: |- 8 | {{ include "gen/root/INSTALL.inc.md" }} 9 | Synonyms: 10 | Related: 11 | - DOWNLOAD 12 | - supported-platforms 13 | - compatibility 14 | -------------------------------------------------------------------------------- /gen/root/README_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: README 2 | Title: >- 3 | Murex 4 | CategoryID: Murex 5 | Summary: 6 | A smarter $SHELL and scripting environment with advanced features designed for safety and productivity. Murex is a modern shell 7 | Description: |- 8 | {{ include "gen/root/README.inc.md" }} 9 | Synonyms: 10 | Related: -------------------------------------------------------------------------------- /gen/root/compatibility_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: compatibility 2 | Title: >- 3 | Compatibility Commitment 4 | CategoryID: Murex 5 | Summary: >- 6 | Murex is committed to excellent backwards compatibility 7 | Description: |- 8 | {{ include "gen/root/compatibility.inc.md" }} 9 | Synonyms: 10 | Related: 11 | - INSTALL 12 | - CONTRIBUTING 13 | -------------------------------------------------------------------------------- /gen/root/supported-platforms_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: supported-platforms 2 | WriteTo: docs/ 3 | Title: >- 4 | Supported Platforms 5 | CategoryID: Murex 6 | Summary: >- 7 | Operating systems and CPU architectures supported by Murex 8 | Description: |- 9 | {{ include "gen/root/supported-platforms.inc.md" }} 10 | Synonyms: 11 | Related: 12 | - DOWNLOAD 13 | - INSTALL 14 | -------------------------------------------------------------------------------- /gen/root/tour_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: tour 2 | WriteTo: docs/ 3 | Title: >- 4 | Language Tour 5 | CategoryID: Murex 6 | Summary: >- 7 | Getting started with Murex: a quick tour of the next generation of shell scripting 8 | Description: |- 9 | {{ include "gen/root/tour.inc.md" }} 10 | Synonyms: 11 | Related: 12 | - INSTALL 13 | - operators-and-tokens -------------------------------------------------------------------------------- /gen/user-guide/arrays_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: murex-arrays 2 | Title: >- 3 | Working With Arrays 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.beginners 7 | Summary: >- 8 | Examples using arrays within Murex 9 | Description: |- 10 | {{ include "gen/user-guide/arrays.inc.md" }} 11 | Detail: 12 | Related: 13 | - expr 14 | - addition 15 | - subtract-by 16 | - multiply-by 17 | - divide-by 18 | - int 19 | - float 20 | - num 21 | - config 22 | - cast 23 | - operators-and-tokens -------------------------------------------------------------------------------- /gen/user-guide/data-types.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: data-types 2 | Title: >- 3 | Data Types 4 | CategoryID: user-guide 5 | Summary: >- 6 | Defining the type of data 7 | Description: |- 8 | {{ include "gen/user-guide/data-types.inc.md" }} 9 | Synonyms: 10 | - job-control 11 | Related: 12 | - cast 13 | - function 14 | - method 15 | - set 16 | - type 17 | - format 18 | -------------------------------------------------------------------------------- /gen/user-guide/hint-text_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: hint-text 2 | Title: >- 3 | Hint Text 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.readmore 7 | Summary: >- 8 | A status bar for your shell 9 | Description: |- 10 | {{ include "gen/user-guide/hint-text.inc.md" }} 11 | Synonyms: 12 | Related: 13 | - interactive-shell 14 | - config 15 | 16 | 17 | -------------------------------------------------------------------------------- /gen/user-guide/integrations_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: integrations 2 | Title: >- 3 | Integrations 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.readmore 7 | Summary: >- 8 | Default integrations shipped with Murex 9 | Description: |- 10 | {{ include "gen/user-guide/integrations.inc.md" }} 11 | Synonyms: 12 | Related: 13 | - modules 14 | - spellcheck 15 | - fileref 16 | - profile -------------------------------------------------------------------------------- /gen/user-guide/job-control_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: job-control 2 | Title: >- 3 | Job Control 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.readmore 7 | Summary: >- 8 | How to manage jobs with Murex 9 | Description: |- 10 | {{ include "gen/user-guide/job-control.inc.md" }} 11 | Synonyms: 12 | - job-control 13 | Related: 14 | - bg 15 | - fg 16 | - fid-kill 17 | - fid-list 18 | - exec 19 | - fexec 20 | - jobs 21 | - terminal-keys 22 | -------------------------------------------------------------------------------- /gen/user-guide/operators-tokens_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: operators-and-tokens 2 | Title: >- 3 | Operators And Tokens 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.reference 7 | Summary: >- 8 | All supported operators and tokens 9 | Description: |- 10 | {{ include "gen/includes/expr-operators-tokens.inc.md" }} 11 | Synonyms: 12 | Related: 13 | - expr 14 | - tour -------------------------------------------------------------------------------- /gen/user-guide/terminal-keys_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: terminal-keys 2 | Title: >- 3 | Terminal Hotkeys 4 | CategoryID: user-guide 5 | SubCategoryIDs: 6 | - guide.beginners 7 | - guide.reference 8 | Summary: >- 9 | A list of all the terminal hotkeys and their uses 10 | Description: |- 11 | {{ include "gen/user-guide/terminal-keys.inc.md" }} 12 | Synonyms: 13 | - hotkeys 14 | Related: 15 | - interactive-shell 16 | - rosetta-stone 17 | - spellcheck 18 | -------------------------------------------------------------------------------- /gen/userguide-vue-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ vuepressmenu "user-guide" }} -------------------------------------------------------------------------------- /gen/variables-md-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ if env "DOCGEN_TARGET=vuepress" }}--- 2 | index: true 3 | description: {{ quote .Summary }} 4 | category: {{ .Title }} 5 | --- 6 | 7 | {{ end }}# {{ md .Title }}{{ if .Description }} 8 | 9 | {{ md (include .Description) }}{{ end }} 10 | 11 | ## Pages 12 | 13 | {{ if .Documents }}{{ range $i,$a := .Documents }}{{ if gt $i 0 }} 14 | {{ end }}* [{{ md .Title }}](../{{ md .Hierarchy }}.md): 15 | {{ md .Summary }}{{ end }}{{ else }}No pages currently exist for this category.{{ end }} -------------------------------------------------------------------------------- /gen/variables-vue-cat.tmpl: -------------------------------------------------------------------------------- 1 | {{ vuepressmenu "variables" }} -------------------------------------------------------------------------------- /gen/variables/HOSTNAME_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: hostname 2 | Title: >- 3 | `HOSTNAME` (str) 4 | CategoryID: variables 5 | SubCategoryIDs: [ vars.reserved ] 6 | Summary: >- 7 | Hostname of the current machine 8 | Description: |- 9 | `HOSTNAME` returns the hostname of the machine (host / server / virtual machine 10 | / et al) that Murex is running from. 11 | 12 | {{ include "gen/includes/this-is-a-reserved-var.inc.md" }} 13 | Synonyms: 14 | - hostname 15 | - HOSTNAME 16 | Related: 17 | - str 18 | - reserved-vars 19 | 20 | -------------------------------------------------------------------------------- /gen/variables/PWD_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: pwd 2 | Title: >- 3 | `PWD` (path) 4 | CategoryID: variables 5 | SubCategoryIDs: [ vars.posix, vars.env ] 6 | Summary: >- 7 | Current working directory 8 | Description: |- 9 | `PWD` is an environmental variable containing the current working directory. 10 | 11 | It is updated via `cd` however you can overwrite its value manually via `export`. 12 | Examples: 13 | Synonyms: 14 | - pwd 15 | - PWD 16 | Related: 17 | - path 18 | - pwdhist 19 | - export 20 | - cd 21 | -------------------------------------------------------------------------------- /gen/variables/TMPDIR_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: tmpdir 2 | Title: >- 3 | `TMPDIR` (path) 4 | CategoryID: variables 5 | SubCategoryIDs: [ vars.posix ] 6 | Summary: >- 7 | Return the temporary directory 8 | Description: |- 9 | `TMPDIR` returns the temporary directory. 10 | 11 | {{ include "gen/includes/this-is-a-reserved-var.inc.md" }} 12 | Detail: 13 | Synonyms: 14 | - tmpdir 15 | - TMPDIR 16 | Related: 17 | - path 18 | - reserved-vars 19 | - tilde 20 | 21 | 22 | -------------------------------------------------------------------------------- /gen/variables/USER_doc.yaml: -------------------------------------------------------------------------------- 1 | - DocumentID: user 2 | Title: >- 3 | `USER` (str) 4 | CategoryID: variables 5 | SubCategoryIDs: [ vars.reserved, vars.posix ] 6 | Summary: >- 7 | Username for the current session 8 | Description: |- 9 | `USER` returns the user name of the current Murex session. 10 | 11 | {{ include "gen/includes/this-is-a-reserved-var.inc.md" }} 12 | Synonyms: 13 | - user 14 | - USER 15 | Related: 16 | - str 17 | - reserved-vars 18 | - logname 19 | 20 | -------------------------------------------------------------------------------- /gen/vuepress/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /gen/vuepress/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /gen/vuepress/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/apple-touch-icon.png -------------------------------------------------------------------------------- /gen/vuepress/public/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/download.png -------------------------------------------------------------------------------- /gen/vuepress/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/favicon-16x16.png -------------------------------------------------------------------------------- /gen/vuepress/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/favicon-32x32.png -------------------------------------------------------------------------------- /gen/vuepress/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/favicon.ico -------------------------------------------------------------------------------- /gen/vuepress/public/git-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/git-autocomplete.png -------------------------------------------------------------------------------- /gen/vuepress/public/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/keyboard.png -------------------------------------------------------------------------------- /gen/vuepress/public/og-murex-v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/og-murex-v1.png -------------------------------------------------------------------------------- /gen/vuepress/public/og-murex-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/og-murex-v2.png -------------------------------------------------------------------------------- /gen/vuepress/public/og-murex-v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/og-murex-v3.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-autocomplete-context-sensitive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-autocomplete-context-sensitive.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-autocomplete-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-autocomplete-git.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-error-messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-error-messages.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-hint-starship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-hint-starship.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-hint-text-egrep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-hint-text-egrep.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-hint-text-rsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-hint-text-rsync.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-hint-text-uptime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-hint-text-uptime.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-history.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-kill-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-kill-autocomplete.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-open-foreach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-open-foreach.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-paste-safety.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-paste-safety.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-preview-command-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-preview-command-line.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-preview-custom-hints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-preview-custom-hints.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-preview-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-preview-image.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-preview-man-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-preview-man-page.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-preview-man-rsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-preview-man-rsync.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-ps-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-ps-select.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-spellchecker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-spellchecker.png -------------------------------------------------------------------------------- /gen/vuepress/public/screenshot-supports-posix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/vuepress/public/screenshot-supports-posix.png -------------------------------------------------------------------------------- /gen/vuepress/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /gen/vuepress/styles/config.scss: -------------------------------------------------------------------------------- 1 | // you can change config here 2 | $colors: #c0392b, #d35400, #f39c12, #27ae60, #16a085, #2980b9, #8e44ad, #2c3e50, 3 | #7f8c8d !default; 4 | -------------------------------------------------------------------------------- /gen/vuepress/styles/palette.scss: -------------------------------------------------------------------------------- 1 | // you can change colors here 2 | $theme-color: #268bd2; 3 | $quote-color: #850; 4 | $code-color: #0f600f; 5 | 6 | // this needs to be quoted 7 | $font-family: "Lato, sans-serif"; 8 | // this SHOULDN'T be quoted 9 | $font-title: Jura, sans-serif; 10 | $font-strong: Lato, sans-serif; 11 | $font-italic: "Libre Baskerville", Lato, sans-serif; -------------------------------------------------------------------------------- /gen/website/404.md: -------------------------------------------------------------------------------- 1 | # File Not Found! 2 | 3 | If you wish to report this as a bug then you can do so at [Murex's Github repository](https://github.com/lmorg/murex/issues). 4 | 5 | Alternatively this project also welcomes other contributors, should you wish to submit your own pull request. 6 | -------------------------------------------------------------------------------- /gen/website/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/website/assets/favicon-16x16.png -------------------------------------------------------------------------------- /gen/website/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/website/assets/favicon-32x32.png -------------------------------------------------------------------------------- /gen/website/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/gen/website/assets/favicon.ico -------------------------------------------------------------------------------- /images/blog/split_personalities/conflict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/blog/split_personalities/conflict.png -------------------------------------------------------------------------------- /images/blog/split_personalities/murex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/blog/split_personalities/murex.png -------------------------------------------------------------------------------- /images/blog/split_personalities/new.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/blog/split_personalities/new.jpg -------------------------------------------------------------------------------- /images/blog/split_personalities/old.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/blog/split_personalities/old.jpg -------------------------------------------------------------------------------- /images/blog/split_personalities/thompson.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/blog/split_personalities/thompson.jpg -------------------------------------------------------------------------------- /images/screenshot-autocomplete-context-sensitive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-autocomplete-context-sensitive.png -------------------------------------------------------------------------------- /images/screenshot-autocomplete-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-autocomplete-git.png -------------------------------------------------------------------------------- /images/screenshot-error-messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-error-messages.png -------------------------------------------------------------------------------- /images/screenshot-hint-starship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-hint-starship.png -------------------------------------------------------------------------------- /images/screenshot-hint-text-rsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-hint-text-rsync.png -------------------------------------------------------------------------------- /images/screenshot-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-history.png -------------------------------------------------------------------------------- /images/screenshot-iterm2-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-iterm2-open.png -------------------------------------------------------------------------------- /images/screenshot-kill-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-kill-autocomplete.png -------------------------------------------------------------------------------- /images/screenshot-kitty-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-kitty-open.png -------------------------------------------------------------------------------- /images/screenshot-open-foreach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-open-foreach.png -------------------------------------------------------------------------------- /images/screenshot-paste-safety.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-paste-safety.png -------------------------------------------------------------------------------- /images/screenshot-preview-command-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-preview-command-line.png -------------------------------------------------------------------------------- /images/screenshot-preview-custom-hints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-preview-custom-hints.png -------------------------------------------------------------------------------- /images/screenshot-preview-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-preview-image.png -------------------------------------------------------------------------------- /images/screenshot-preview-man-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-preview-man-page.png -------------------------------------------------------------------------------- /images/screenshot-preview-man-rsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-preview-man-rsync.png -------------------------------------------------------------------------------- /images/screenshot-ps-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-ps-select.png -------------------------------------------------------------------------------- /images/screenshot-spellchecker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-spellchecker.png -------------------------------------------------------------------------------- /images/screenshot-supports-posix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-supports-posix.png -------------------------------------------------------------------------------- /images/screenshot-terminology-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/images/screenshot-terminology-open.png -------------------------------------------------------------------------------- /integrations/aspell_any.mx: -------------------------------------------------------------------------------- 1 | if { which aspell } then { 2 | config set shell spellcheck-enabled true 3 | } 4 | -------------------------------------------------------------------------------- /integrations/aws_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete set aws %[ 2 | { 3 | CacheTTL: 31536000 # 1 year 4 | Dynamic: '{ 5 | cast str 6 | config set proc strict-arrays false 7 | exec aws @PARAMS help -> [^AVAILABLE..^SEE ALSO]re8bt -> regexp (f/^o (.*)/) 8 | exec aws @PARAMS help -> man-get-flags -> format str 9 | }' 10 | DynamicPreview: '{ 11 | config set proc strict-arrays false 12 | exec aws @PARAMS help 13 | }' 14 | AllowMultiple: true 15 | AllowAny: true 16 | } 17 | ] -------------------------------------------------------------------------------- /integrations/bash_posix.mx: -------------------------------------------------------------------------------- 1 | define-force-tty-func bash -------------------------------------------------------------------------------- /integrations/coreutils_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete set cd %[{ 2 | IncDirs: true 3 | }] 4 | 5 | autocomplete set mkdir %[{ 6 | IncDirs: true 7 | AllowMultiple: true 8 | IncManPage: true 9 | }] 10 | 11 | autocomplete set rmdir %[{ 12 | IncDirs: true 13 | AllowMultiple: true 14 | IncManPage: true 15 | }] 16 | 17 | autocomplete set which %[{ 18 | IncExePath: true 19 | AllowMultiple: true 20 | }] 21 | 22 | autocomplete set whereis %[{ 23 | IncExePath: true 24 | AllowMultiple: true 25 | }] -------------------------------------------------------------------------------- /integrations/coreutils_posix.mx: -------------------------------------------------------------------------------- 1 | autocomplete set man %[{ 2 | IncExePath: true 3 | }] 4 | 5 | autocomplete set man-summary %[{ 6 | IncExePath: true 7 | AllowMultiple: true 8 | }] 9 | 10 | autocomplete set sudo %[ 11 | { 12 | IncFiles: true 13 | IncDirs: true 14 | IncExePath: true 15 | } 16 | { 17 | NestedCommand: true 18 | } 19 | ] 20 | 21 | #alias ls=ls --color=auto 22 | alias grep=grep --color=auto 23 | alias egrep=grep -E --color=auto 24 | 25 | $ENV.CLICOLOR = true -------------------------------------------------------------------------------- /integrations/dd_posix.mx: -------------------------------------------------------------------------------- 1 | autocomplete set dd %[ 2 | { 3 | Flags: [ "if=", "of=", "bs=", "iflag=", "oflag=", "count=", "status=" ] 4 | FlagValues: { 5 | "if": [{ 6 | IncFiles: true 7 | }] 8 | "of": [{ 9 | IncFiles: true 10 | }] 11 | "*": [{ 12 | AllowAny: true 13 | }] 14 | } 15 | } 16 | { 17 | Goto: "/0" 18 | } 19 | ] -------------------------------------------------------------------------------- /integrations/docker_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete: set docker %[ 2 | { 3 | DynamicDesc: '{ 4 | docker help -> [^Usage:..]re -> tabulate: --split-comma --map 5 | }' 6 | 7 | ListView: true 8 | 9 | FlagValues: { 10 | "": [{ 11 | DynamicDesc: '{ 12 | docker help $1 -> [^Usage:..]re -> tabulate: --split-comma --map 13 | }' 14 | }] 15 | } 16 | } 17 | { 18 | IncFiles: true 19 | } 20 | ] -------------------------------------------------------------------------------- /integrations/find_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete: set find %[ 2 | { 3 | IncDirs: true 4 | } 5 | { 6 | IncManPage: true 7 | ListView: true 8 | FlagValues: { 9 | "": [{ 10 | AllowAny: true 11 | Optional: true 12 | AllowMultiple: true 13 | }] 14 | } 15 | } 16 | { 17 | AllowAny: true 18 | Optional: true 19 | } 20 | { 21 | Goto: "/1" 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /integrations/go_plan9.mx: -------------------------------------------------------------------------------- 1 | private go-package { 2 | # returns all the packages in $GOPATH 3 | g $GOPATH/src/* -> f +d 4 | } 5 | -------------------------------------------------------------------------------- /integrations/go_posix.mx: -------------------------------------------------------------------------------- 1 | private go-package { 2 | # returns all the packages in $GOPATH 3 | find $GOPATH/src/ -type d -not -path */.* -> sed -r s:$GOPATH/src/:: 4 | } 5 | -------------------------------------------------------------------------------- /integrations/go_windows.mx: -------------------------------------------------------------------------------- 1 | private go-package { 2 | # returns all the packages in $GOPATH 3 | g $GOPATH/src/* -> f +d 4 | } 5 | -------------------------------------------------------------------------------- /integrations/godoc.go: -------------------------------------------------------------------------------- 1 | // Package integrations is a repository of autocompletes and other Murex tooling for 3rd party executables 2 | package integrations 3 | -------------------------------------------------------------------------------- /integrations/gopass_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete: set gopass %[{ 2 | Flags: [ 3 | --yes 4 | --clip 5 | -c 6 | --help 7 | -h 8 | --version 9 | -v 10 | ] 11 | AllowMultiple: true 12 | Dynamic: '{ exec: @ARGS --generate-bash-completion }' 13 | AutoBranch: true 14 | }] -------------------------------------------------------------------------------- /integrations/helix-editor_posix.mx: -------------------------------------------------------------------------------- 1 | if { which helix } then { 2 | summary helix "Helix: a post-modern text editor" 3 | 4 | alias helix=exec $MUREX_EXE -quiet -setsid -execute exec helix 5 | } 6 | 7 | if { which hx } then { 8 | summary hx "Helix: a post-modern text editor" 9 | 10 | alias hx=exec $MUREX_EXE -setsid -quiet -execute exec hx 11 | } 12 | -------------------------------------------------------------------------------- /integrations/orbstack_darwin.mx: -------------------------------------------------------------------------------- 1 | if { which orb } then { 2 | return 3 | } 4 | 5 | autocomplete set orb %[ 6 | { 7 | DynamicDesc: '{ 8 | config set proc strict-arrays false 9 | exec orbctl @PARAMS --help -> tabulate --split-comma --map 10 | }' 11 | } 12 | ] 13 | 14 | autocomplete get orb -> autocomplete set orbctl 15 | 16 | define-force-tty-func orb 17 | define-force-tty-func orbctl 18 | 19 | summary orb "OrbStack: K8s, Docker and Linux virtualization" 20 | summary orbctl ${ runtime --summaries -> [orb] } -------------------------------------------------------------------------------- /integrations/su_linux.mx: -------------------------------------------------------------------------------- 1 | private autocomplete.su { 2 | # Autocomplete suggestion for `su` 3 | test define getent { 4 | "ExitNum": 0 5 | } 6 | 7 | trypipe { 8 | getent passwd -> cut -d: -f1 -> sed -e "/^${ whoami }$/d" -> jsplit \n 9 | } 10 | } 11 | 12 | test unit private autocomplete.su %{ 13 | StdoutType: json 14 | StdoutGreaterThan: 1 15 | StdoutIsArray: true 16 | } 17 | 18 | autocomplete set su %[{ 19 | Dynamic: %({ autocomplete.su }) 20 | IncManPage: true 21 | }] 22 | 23 | -------------------------------------------------------------------------------- /integrations/terraform-docs_any.mx: -------------------------------------------------------------------------------- 1 | autocomplete: set terraform-docs %[ 2 | { 3 | DynamicDesc: '{ 4 | cast json 5 | config set proc strict-arrays false 6 | terraform-docs @PARAMS --help -> tabulate --key-value --map --split-comma --key-inc-hint 7 | }' 8 | AllowMultiple: true 9 | AllowAny: true 10 | ListView: true 11 | } 12 | ] -------------------------------------------------------------------------------- /integrations/tset_posix.mx: -------------------------------------------------------------------------------- 1 | define-force-tty-func tset 2 | define-force-tty-func reset -------------------------------------------------------------------------------- /integrations/vscode.mx: -------------------------------------------------------------------------------- 1 | if { which code } then { 2 | autocomplete code %[ 3 | { 4 | DynamicDesc: '{ 5 | code --help -> tabulate --map --split-space --key-inc-hint 6 | }' 7 | } 8 | ] 9 | } 10 | 11 | !if { man-summary atom } then { 12 | summary atom "Github Atom - Text editor / IDE" 13 | } 14 | 15 | !if { man-summary code } then { 16 | summary code "Microsoft Visual Studio Code - Text editor / IDE" 17 | } -------------------------------------------------------------------------------- /integrations/zfs_posix.mx: -------------------------------------------------------------------------------- 1 | autocomplete set zfs %[{ 2 | Dynamic: %({ 3 | zfs \ 4 | -> grep -E "^\t[a-z]+" \ 5 | -> regexp 'f/\t+([a-z]+)/' \ 6 | -> uniq 7 | }) 8 | }] 9 | 10 | autocomplete set zpool %[{ 11 | Dynamic: %({ 12 | zpool \ 13 | -> grep -E "^\t[a-z]+" \ 14 | -> regexp 'f/\t+([a-z]+)/' \ 15 | -> uniq 16 | }) 17 | }] 18 | -------------------------------------------------------------------------------- /integrations/zzz_example_any.mx: -------------------------------------------------------------------------------- 1 | # this file will be executed on all systems -------------------------------------------------------------------------------- /integrations/zzz_example_darwin.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on macOS systems -------------------------------------------------------------------------------- /integrations/zzz_example_dragonfly.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on DragonflyBSD systems -------------------------------------------------------------------------------- /integrations/zzz_example_freebsd.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on FreeBSD systems -------------------------------------------------------------------------------- /integrations/zzz_example_linux.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on Linux systems -------------------------------------------------------------------------------- /integrations/zzz_example_netbsd.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on NetBSD systems -------------------------------------------------------------------------------- /integrations/zzz_example_openbsd.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on OpenBSD systems -------------------------------------------------------------------------------- /integrations/zzz_example_plan9.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on Plan 9 systems -------------------------------------------------------------------------------- /integrations/zzz_example_posix.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on POSIX systems, which include Linux, macOS, 2 | # BSD and Solaris -------------------------------------------------------------------------------- /integrations/zzz_example_solaris.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on Solaris systems -------------------------------------------------------------------------------- /integrations/zzz_example_windows.mx: -------------------------------------------------------------------------------- 1 | # this file will only be executed on Windows systems -------------------------------------------------------------------------------- /integrations/zzz_integrations_any.go: -------------------------------------------------------------------------------- 1 | package integrations 2 | 3 | import ( 4 | "embed" 5 | ) 6 | 7 | //go:embed *_any.mx 8 | var resAny embed.FS 9 | 10 | func init() { 11 | resources["*_any"] = &resAny 12 | } 13 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | // +build darwin 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_darwin.mx 11 | var resDarwin embed.FS 12 | 13 | func init() { 14 | resources["*_darwin"] = &resDarwin 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_dragonfly.go: -------------------------------------------------------------------------------- 1 | //go:build dragonfly 2 | // +build dragonfly 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_dragonfly.mx 11 | var resDragonfly embed.FS 12 | 13 | func init() { 14 | resources["*_dragonfly"] = &resDragonfly 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_freebsd.go: -------------------------------------------------------------------------------- 1 | //go:build freebsd 2 | // +build freebsd 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_freebsd.mx 11 | var resFreeBSD embed.FS 12 | 13 | func init() { 14 | resources["*_freebsd"] = &resFreeBSD 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_linux.mx 11 | var resLinux embed.FS 12 | 13 | func init() { 14 | resources["*_linux"] = &resLinux 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_netbsd.go: -------------------------------------------------------------------------------- 1 | //go:build netbsd 2 | // +build netbsd 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_netbsd.mx 11 | var resNetBSD embed.FS 12 | 13 | func init() { 14 | resources["*_netbsd"] = &resNetBSD 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_openbsd.go: -------------------------------------------------------------------------------- 1 | //go:build openbsd 2 | // +build openbsd 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_openbsd.mx 11 | var resOpenBSD embed.FS 12 | 13 | func init() { 14 | resources["*_openbsd"] = &resOpenBSD 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_plan9.mx 11 | var resPlan9 embed.FS 12 | 13 | func init() { 14 | resources["*_plan9"] = &resPlan9 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_posix.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && !plan9 2 | // +build !windows,!plan9 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_posix.mx 11 | var resPOSIX embed.FS 12 | 13 | func init() { 14 | resources["*_posix"] = &resPOSIX 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_solaris.go: -------------------------------------------------------------------------------- 1 | //go:build solaris 2 | // +build solaris 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_solaris.mx 11 | var resSolaris embed.FS 12 | 13 | func init() { 14 | resources["*_solaris"] = &resSolaris 15 | } 16 | -------------------------------------------------------------------------------- /integrations/zzz_integrations_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package integrations 5 | 6 | import ( 7 | "embed" 8 | ) 9 | 10 | //go:embed *_windows.mx 11 | var resWindows embed.FS 12 | 13 | func init() { 14 | resources["*_windows"] = &resWindows 15 | } 16 | -------------------------------------------------------------------------------- /lang/define_getters_test.go: -------------------------------------------------------------------------------- 1 | package lang 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang/types" 7 | "github.com/lmorg/murex/test/count" 8 | ) 9 | 10 | func TestGetExtType(t *testing.T) { 11 | count.Tests(t, 2) 12 | 13 | fileExts = map[string]string{"foo": "bar"} 14 | 15 | if GetExtType("FOO") != "bar" { 16 | t.Error("foo != bar") 17 | } 18 | 19 | if GetExtType("l;dskjforijf;sdj;oweirnfifunweodijn") != types.Generic { 20 | t.Error("Undefined ext != generic") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lang/exec_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package lang 5 | 6 | import ( 7 | "syscall" 8 | ) 9 | 10 | func unixProcAttrFauxTTY() *syscall.SysProcAttr { 11 | return nil 12 | } 13 | 14 | func UnixPidToFg(_ *Process) {} 15 | -------------------------------------------------------------------------------- /lang/exec_notwin.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package lang 5 | 6 | func osExecGetArgv(p *Process) []string { 7 | return p.Parameters.StringArray() 8 | } 9 | -------------------------------------------------------------------------------- /lang/exec_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package lang 5 | 6 | import ( 7 | "syscall" 8 | ) 9 | 10 | func unixProcAttrFauxTTY() *syscall.SysProcAttr { 11 | return nil 12 | } 13 | 14 | func UnixPidToFg(_ *Process) {} 15 | -------------------------------------------------------------------------------- /lang/exec_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package lang 5 | 6 | import ( 7 | "syscall" 8 | ) 9 | 10 | func osExecGetArgv(p *Process) []string { 11 | argv := []string{"cmd", "/c"} 12 | argv = append(argv, p.Parameters.StringArray()...) 13 | return argv 14 | } 15 | 16 | func unixProcAttrFauxTTY() *syscall.SysProcAttr { 17 | return nil 18 | } 19 | 20 | func UnixPidToFg(_ *Process) {} 21 | -------------------------------------------------------------------------------- /lang/exit.go: -------------------------------------------------------------------------------- 1 | package lang 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | var ( 8 | ProfCpuCleanUp func() = func() {} 9 | ProfMemCleanUp func() = func() {} 10 | ProfTraceCleanUp func() = func() {} 11 | ) 12 | 13 | func Exit(exitNum int) { 14 | ProfCpuCleanUp() 15 | ProfMemCleanUp() 16 | ProfTraceCleanUp() 17 | 18 | os.Exit(exitNum) 19 | } 20 | -------------------------------------------------------------------------------- /lang/expressions/parse_number.go: -------------------------------------------------------------------------------- 1 | package expressions 2 | 3 | func (tree *ParserT) parseNumber() []rune { 4 | start := tree.charPos 5 | 6 | for tree.charPos++; tree.charPos < len(tree.expression); tree.charPos++ { 7 | r := tree.expression[tree.charPos] 8 | 9 | switch { 10 | case (r >= '0' && '9' >= r) || r == '.': 11 | // valid numeric character 12 | 13 | default: 14 | // not a number 15 | goto endNumber 16 | } 17 | } 18 | 19 | endNumber: 20 | return tree.expression[start:tree.charPos] 21 | } 22 | -------------------------------------------------------------------------------- /lang/expressions/parse_quoteBT_test.go: -------------------------------------------------------------------------------- 1 | package expressions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test" 7 | ) 8 | 9 | func TestParseQuoteBackTicks(t *testing.T) { 10 | tests := []test.MurexTest{ 11 | { 12 | Block: "echo `foobar`", 13 | Stdout: "'foobar'\n", 14 | }, 15 | } 16 | 17 | test.RunMurexTests(tests, t) 18 | } 19 | -------------------------------------------------------------------------------- /lang/expressions/primitives/primitives_test.go: -------------------------------------------------------------------------------- 1 | package primitives 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/lang/types" 7 | "github.com/lmorg/murex/test/count" 8 | ) 9 | 10 | // https://github.com/lmorg/murex/issues/845 11 | func TestGenericsIssue845(t *testing.T) { 12 | count.Tests(t, 1) 13 | 14 | if DataType2Primitive(types.Generic) != String { 15 | t.Error("generics should be treated like strings") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lang/expressions/testcode/testcode_ac_element.mx: -------------------------------------------------------------------------------- 1 | autocomplete: set "[[" { [{ 2 | "AnyValue": true, 3 | "ExecCmdline": true, 4 | "AutoBranch": true, 5 | "Dynamic": ({ -> struct-keys -> append "]]" }) 6 | } ]} -------------------------------------------------------------------------------- /lang/expressions/testcode/testcode_aws.mx: -------------------------------------------------------------------------------- 1 | if { which aws } then { 2 | autocomplete set aws [{ 3 | "CacheTTL": 31536000, # 1 year 4 | "Dynamic": ({ 5 | cast: str 6 | config: set proc strict-arrays false 7 | aws: @PARAMS help -> @[^AVAILABLE..^SEE ALSO]re8bt -> regexp: (f/^o (.*)/) 8 | aws: @PARAMS help -> man-get-flags -> format: str 9 | }), 10 | "AllowMultiple": true, 11 | "AllowAny": true 12 | }] 13 | } -------------------------------------------------------------------------------- /lang/expressions/testcode/testcode_if_else_fn.mx: -------------------------------------------------------------------------------- 1 | if { = `${os}` != `windows` } then { 2 | function agent { 3 | # Launch ssh-agent 4 | config: set proc strict-arrays false 5 | ssh-agent -> head -n2 -> [ :0 ] -> prefix "export " -> source 6 | ssh-add: @{g ~/.ssh/*.key} @{g ~/.ssh/*.pem} 7 | } 8 | 9 | } else { 10 | function agent { 11 | # On POSIX systems this would launch `ssh-agent` however on Windows it is an empty function 12 | } 13 | } -------------------------------------------------------------------------------- /lang/fork_release.go: -------------------------------------------------------------------------------- 1 | //go:build !trace 2 | // +build !trace 3 | 4 | package lang 5 | 6 | func forkCheckForNils(fork *Fork) {} 7 | -------------------------------------------------------------------------------- /lang/fork_trace.go: -------------------------------------------------------------------------------- 1 | //go:build trace 2 | // +build trace 3 | 4 | package lang 5 | 6 | func forkCheckForNils(fork *Fork) { 7 | switch { 8 | case fork.FileRef == nil: 9 | panic("fork.FileRef == nil in (fork *Fork).Execute()") 10 | case fork.FileRef.Source == nil: 11 | panic("fork.FileRef.Source == nil in (fork *Fork).Execute()") 12 | case fork.FileRef.Source.Module == "": 13 | panic("missing module name in (fork *Fork).Execute()") 14 | case fork.Name.String() == "": 15 | panic("missing function name in (fork *Fork).Execute()") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lang/godoc.go: -------------------------------------------------------------------------------- 1 | // Package lang provides the parser for the murex shell scripting language 2 | package lang 3 | -------------------------------------------------------------------------------- /lang/ipc/ipc_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | // +build ignore 3 | 4 | //// +build windows plan9 js 5 | 6 | package ipc 7 | 8 | import ( 9 | "errors" 10 | "net" 11 | ) 12 | 13 | var errUnsupported = errors.New("peercred is unsupported on this operating system") 14 | 15 | // Read returns peer credentials using the SO_PEERCRED socket option on 16 | // Unix domain sockets. 17 | // 18 | // On unsupported operating systems it returns an error. 19 | func Read(conn *net.UnixConn) (*Cred, error) { 20 | return nil, errUnsupported 21 | } 22 | -------------------------------------------------------------------------------- /lang/jobs_helper_test.go: -------------------------------------------------------------------------------- 1 | package lang 2 | 3 | // Raw is only used for testing 4 | func (j *jobs) Raw() []*Process { 5 | return j.jobs 6 | } 7 | -------------------------------------------------------------------------------- /lang/parameters/godoc.go: -------------------------------------------------------------------------------- 1 | // Package parameters provides parsing for language command line parameters within murex 2 | package parameters 3 | -------------------------------------------------------------------------------- /lang/pipes/godoc.go: -------------------------------------------------------------------------------- 1 | // Package pipes provides runtime information about murex named pipes 2 | package pipes 3 | -------------------------------------------------------------------------------- /lang/process/background.go: -------------------------------------------------------------------------------- 1 | package process 2 | 3 | import "sync/atomic" 4 | 5 | type AtomicBool struct { 6 | i int32 7 | } 8 | 9 | func (ab *AtomicBool) Get() bool { 10 | return atomic.LoadInt32(&ab.i) != 0 11 | } 12 | 13 | func (ab *AtomicBool) Set(v bool) { 14 | if v { 15 | atomic.StoreInt32(&ab.i, 1) 16 | return 17 | } 18 | 19 | atomic.StoreInt32(&ab.i, 0) 20 | } 21 | 22 | func (ab *AtomicBool) String() string { 23 | if ab.Get() { 24 | return "yes" 25 | } 26 | 27 | return "no" 28 | } 29 | -------------------------------------------------------------------------------- /lang/process/name.go: -------------------------------------------------------------------------------- 1 | package process 2 | 3 | import "sync" 4 | 5 | type Name struct { 6 | mutex sync.RWMutex 7 | name string 8 | } 9 | 10 | func (n *Name) Set(s string) { 11 | n.mutex.Lock() 12 | n.name = s 13 | n.mutex.Unlock() 14 | } 15 | 16 | func (n *Name) SetRune(r []rune) { 17 | n.mutex.Lock() 18 | n.name = string(r) 19 | n.mutex.Unlock() 20 | } 21 | 22 | func (n *Name) String() string { 23 | n.mutex.RLock() 24 | s := n.name 25 | n.mutex.RUnlock() 26 | 27 | return s 28 | } 29 | 30 | func (n *Name) Append(s string) { 31 | n.mutex.Lock() 32 | n.name += s 33 | n.mutex.Unlock() 34 | } 35 | -------------------------------------------------------------------------------- /lang/process_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build windows || plan9 || js 2 | // +build windows plan9 js 3 | 4 | package lang 5 | 6 | import ( 7 | "github.com/lmorg/murex/builtins/pipes/streams" 8 | "github.com/lmorg/murex/lang/types" 9 | ) 10 | 11 | func ttys(p *Process) { 12 | if p.CCExists != nil && p.CCExists(p.Name.String()) { 13 | p.Stderr, p.CCErr = streams.NewTee(p.Stderr) 14 | p.CCErr.SetDataType(types.Generic) 15 | 16 | p.Stdout, p.CCOut = streams.NewTee(p.Stdout) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lang/ref/godoc.go: -------------------------------------------------------------------------------- 1 | // Package ref provides some reference structures required by multiple packages 2 | // 3 | // This exists as it's own package to get around cyclic dependencies 4 | package ref 5 | -------------------------------------------------------------------------------- /lang/runmode/godoc.go: -------------------------------------------------------------------------------- 1 | // Package runmode provides constants used to describe the run mode of the murex interpreter 2 | package runmode 3 | -------------------------------------------------------------------------------- /lang/state/functionstate.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | //go:generate stringer -type=FunctionState 4 | 5 | // FunctionState is what the point along the murex pipeline a lang.Process is at 6 | type FunctionState int32 7 | 8 | // The different states available to FunctionState: 9 | const ( 10 | Undefined FunctionState = iota 11 | MemAllocated 12 | Assigned 13 | Starting 14 | Executing 15 | Executed 16 | Terminating 17 | AwaitingGC 18 | Stopped 19 | ) 20 | 21 | func (f FunctionState) State() (state State) { 22 | state.Set(f) 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /lang/state/godoc.go: -------------------------------------------------------------------------------- 1 | // Package state provides constants used to describe the runtime state of murex functions 2 | package state 3 | -------------------------------------------------------------------------------- /lang/stdio/interface_aw.go: -------------------------------------------------------------------------------- 1 | package stdio 2 | 3 | // ArrayWriter is a simple interface types can adopt for buffered writes of formatted arrays in structured types (eg JSON) 4 | type ArrayWriter interface { 5 | Write([]byte) error 6 | WriteString(string) error 7 | Close() error 8 | } 9 | -------------------------------------------------------------------------------- /lang/testdata/fuzz/FuzzParseBlock/2f9cea1e9a87753170ba83bb2697966710f24cb2bdb250a4e9413e3ce93168d0: -------------------------------------------------------------------------------- 1 | go test fuzz v1 2 | string("->->") 3 | -------------------------------------------------------------------------------- /lang/testdata/fuzz/FuzzParseBlock/9a3a0cf65df96f395f456353ed7df0dc1b6ecb660c92d2bc8abfaa135f03f1cb: -------------------------------------------------------------------------------- 1 | go test fuzz v1 2 | string("0 ~->") 3 | -------------------------------------------------------------------------------- /lang/testdata/fuzz/FuzzParseBlock/a54bd97ce43e403dbed2cb42e802a2bd230c78809a69352d33d224bd29e8d81f: -------------------------------------------------------------------------------- 1 | go test fuzz v1 2 | string("[") 3 | -------------------------------------------------------------------------------- /lang/trace_disabled.go: -------------------------------------------------------------------------------- 1 | //go:build !trace 2 | // +build !trace 3 | 4 | package lang 5 | 6 | func trace(_ *Process) {} 7 | -------------------------------------------------------------------------------- /lang/types/datatype.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // DataTypeFromInterface returns the Murex data-type expected to be associated 4 | // with any specific Go data type. 5 | func DataTypeFromInterface(v interface{}) string { 6 | switch v.(type) { 7 | case int: 8 | return Integer 9 | 10 | case float64: 11 | return Number 12 | 13 | case string, []byte, []rune: 14 | return String 15 | 16 | case bool: 17 | return Boolean 18 | 19 | case nil: 20 | return Null 21 | 22 | default: 23 | return Generic 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lang/variables_bugfix_test.go: -------------------------------------------------------------------------------- 1 | package lang_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | func TestBug507(t *testing.T) { 11 | tests := []test.MurexTest{ 12 | { 13 | Block: `%{thing:{stuff:chow}} -> ![ thing ] -> set: TestBug507`, 14 | ExitNum: 0, 15 | }, 16 | } 17 | 18 | test.RunMurexTestsRx(tests, t) 19 | } 20 | -------------------------------------------------------------------------------- /lang/variables_mxinterface.go: -------------------------------------------------------------------------------- 1 | package lang 2 | 3 | type MxInterface interface { 4 | GetValue() interface{} 5 | GetString() string 6 | Set(interface{}, []string) error 7 | New(string) (MxInterface, error) 8 | } 9 | -------------------------------------------------------------------------------- /main_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package main 5 | 6 | import ( 7 | signalhandler "github.com/lmorg/murex/shell/signal_handler" 8 | "github.com/lmorg/murex/shell/signal_handler/sigfns" 9 | ) 10 | 11 | func registerSignalHandlers(interactiveMode bool) { 12 | signalhandler.Handlers = &signalhandler.SignalFunctionsT{ 13 | Sigint: sigfns.Sigint, 14 | Sigterm: sigfns.Sigterm, 15 | } 16 | signalhandler.EventLoop(interactiveMode) 17 | } 18 | -------------------------------------------------------------------------------- /main_unix.go: -------------------------------------------------------------------------------- 1 | //go:build !js && !windows && !plan9 2 | // +build !js,!windows,!plan9 3 | 4 | package main 5 | 6 | import ( 7 | signalhandler "github.com/lmorg/murex/shell/signal_handler" 8 | "github.com/lmorg/murex/shell/signal_handler/sigfns" 9 | ) 10 | 11 | func registerSignalHandlers(interactiveMode bool) { 12 | signalhandler.Handlers = &signalhandler.SignalFunctionsT{ 13 | Sigint: sigfns.Sigint, 14 | Sigterm: sigfns.Sigterm, 15 | Sigquit: sigfns.Sigquit, 16 | Sigtstp: sigfns.Sigtstp, 17 | Sigchld: sigfns.Sigchld, 18 | Sigcont: sigfns.Sigcont, 19 | } 20 | signalhandler.EventLoop(interactiveMode) 21 | } 22 | -------------------------------------------------------------------------------- /main_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package main 5 | 6 | import ( 7 | signalhandler "github.com/lmorg/murex/shell/signal_handler" 8 | "github.com/lmorg/murex/shell/signal_handler/sigfns" 9 | ) 10 | 11 | func registerSignalHandlers(interactiveMode bool) { 12 | signalhandler.Handlers = &signalhandler.SignalFunctionsT{ 13 | Sigint: sigfns.Sigint, 14 | Sigterm: sigfns.Sigterm, 15 | Sigquit: sigfns.Sigquit, 16 | } 17 | signalhandler.EventLoop(interactiveMode) 18 | } 19 | -------------------------------------------------------------------------------- /shell/aspell_test.go: -------------------------------------------------------------------------------- 1 | package shell_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test" 7 | ) 8 | 9 | func TestAspellInstalled(t *testing.T) { 10 | test.InstalledDepsTest(t, "aspell") 11 | } 12 | -------------------------------------------------------------------------------- /shell/autocomplete/README.md: -------------------------------------------------------------------------------- 1 | # Autocomplete complete functions for murex 2 | 3 | The code here is a bit of a mess but there are tests and this package isn't 4 | meant for consumption as a public API anyways. -------------------------------------------------------------------------------- /shell/autocomplete/dynamic_cache.go: -------------------------------------------------------------------------------- 1 | package autocomplete 2 | 3 | type dynamicCacheItemT struct { 4 | Stdout []byte 5 | DataType string 6 | } 7 | -------------------------------------------------------------------------------- /shell/autocomplete/globals.go: -------------------------------------------------------------------------------- 1 | package autocomplete 2 | 3 | import "sync" 4 | 5 | type globalExesT struct { 6 | ptr *map[string]bool 7 | mutex sync.Mutex 8 | } 9 | 10 | func NewGlobalExes() *globalExesT { 11 | ge := new(globalExesT) 12 | ptr := make(map[string]bool) 13 | ge.ptr = &ptr 14 | return ge 15 | } 16 | 17 | func (ge *globalExesT) Get() *map[string]bool { 18 | ge.mutex.Lock() 19 | ptr := ge.ptr 20 | ge.mutex.Unlock() 21 | return ptr 22 | } 23 | 24 | func (ge *globalExesT) Set(ptr *map[string]bool) { 25 | ge.mutex.Lock() 26 | ge.ptr = ptr 27 | ge.mutex.Unlock() 28 | } 29 | -------------------------------------------------------------------------------- /shell/godoc.go: -------------------------------------------------------------------------------- 1 | // Package shell provides sources for the interactive shell 2 | package shell 3 | -------------------------------------------------------------------------------- /shell/hintsummary/readlink.go: -------------------------------------------------------------------------------- 1 | package hintsummary 2 | 3 | import "os" 4 | 5 | func readlink(path string) string { 6 | ln, err := os.Readlink(path) 7 | if err != nil { 8 | return path 9 | } 10 | 11 | return ln 12 | } 13 | -------------------------------------------------------------------------------- /shell/history_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package shell 5 | 6 | import ( 7 | "github.com/lmorg/murex/utils/readline" 8 | ) 9 | 10 | func definePromptHistory() { 11 | // We don't want persistent history when running this from WebAssembly 12 | Prompt.History = &readline.ExampleHistory{} 13 | } 14 | 15 | func setPromptHistory() { 16 | // We don't want persistent history when running this from WebAssembly 17 | Prompt.History = &readline.ExampleHistory{} 18 | } 19 | -------------------------------------------------------------------------------- /shell/parser.go: -------------------------------------------------------------------------------- 1 | package shell 2 | 3 | import ( 4 | "github.com/lmorg/murex/utils/parser" 5 | ) 6 | 7 | func syntaxHighlight(r []rune) string { 8 | _, highlighted := parse(r) 9 | return highlighted 10 | } 11 | 12 | func parse(line []rune) (pt parser.ParsedTokens, syntaxHighlighted string) { 13 | return parser.Parse(line, 0) 14 | } 15 | -------------------------------------------------------------------------------- /shell/preview_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 || windows || js 2 | // +build plan9 windows js 3 | 4 | package shell 5 | 6 | import ( 7 | "github.com/lmorg/murex/utils/readline" 8 | ) 9 | 10 | func previewFile(filename string) []byte { 11 | return nil 12 | } 13 | 14 | func manPage(_ string, _ *readline.PreviewSizeT) []byte { 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /shell/session/session_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build js || windows || plan9 2 | // +build js windows plan9 3 | 4 | package session 5 | 6 | import ( 7 | "runtime" 8 | 9 | "github.com/lmorg/murex/debug" 10 | ) 11 | 12 | func UnixOpenTTY() { 13 | // not supported on this platform 14 | } 15 | 16 | func UnixIsSession() bool { return false } 17 | 18 | func UnixCreateSession() { 19 | debug.Logf("!!! UnixCreateSession is not supported on %s", runtime.GOOS) 20 | } 21 | -------------------------------------------------------------------------------- /shell/signal_handler/sigfns/sigfns_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package sigfns 5 | -------------------------------------------------------------------------------- /shell/signal_handler/sigfns/sigfns_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package sigfns 5 | -------------------------------------------------------------------------------- /shell/signal_handler/signals.go: -------------------------------------------------------------------------------- 1 | package signalhandler 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | var signalChan chan os.Signal = make(chan os.Signal, 1) 8 | 9 | const ( 10 | // PromptEOF defines the string to write when ctrl+d is pressed 11 | PromptEOF = "^D" 12 | 13 | // PromptSIGTSTP defines the string to write when ctrl+z is pressed 14 | PromptSIGTSTP = "^Z" 15 | 16 | // PromptSIGINT defines the string to write when ctrl+c is pressed 17 | PromptSIGINT = "^C" 18 | 19 | // PromptSIGQUIT defines the string to write when ctrl+\ is pressed 20 | PromptSIGQUIT = "^\\" 21 | ) 22 | -------------------------------------------------------------------------------- /shell/signal_handler/signals_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package signalhandler 5 | 6 | // EventLoop is an internal function to capture and handle OS signals. 7 | // However since no signals will be sent via a webpage, this is just an empty 8 | // function when compiled against js/wasm 9 | func EventLoop(_ bool) {} 10 | 11 | func Register(_ bool) {} 12 | 13 | var Handlers *SignalFunctionsT 14 | 15 | type SignalFunctionsT struct{} 16 | -------------------------------------------------------------------------------- /shell/testdata/fuzz/FuzzHint/4928df59d7758237bb59628f7c309030600da0fc130846fb7a56342ffe323871: -------------------------------------------------------------------------------- 1 | go test fuzz v1 2 | string("^[0]") 3 | int(93) 4 | -------------------------------------------------------------------------------- /test/boolean_test.go: -------------------------------------------------------------------------------- 1 | package test_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/lang/expressions" 7 | "github.com/lmorg/murex/test" 8 | ) 9 | 10 | // TestBool proves the boolean test framework works 11 | func TestBool(t *testing.T) { 12 | tests := []test.BooleanTest{ 13 | { 14 | Block: "true", 15 | Result: true, 16 | }, 17 | { 18 | Block: "false", 19 | Result: false, 20 | }, 21 | } 22 | 23 | test.RunBooleanTests(tests, t) 24 | } 25 | -------------------------------------------------------------------------------- /test/buildserver/build.env: -------------------------------------------------------------------------------- 1 | # hard code any env vars needed to compile murex in the develop/latest containers 2 | export MUREX_TEST_SKIP_MAN=1 3 | export MUREX_TEST_SKIP_SPELLCHECK=1 4 | export MUREX_TEST_NO_EXEC_DEPS=1 5 | export GOFLAGS="-buildmode=pie -trimpath" 6 | -------------------------------------------------------------------------------- /test/buildserver/ci.env: -------------------------------------------------------------------------------- 1 | # hard code any env vars needed to test murex in the ci container -------------------------------------------------------------------------------- /test/count/count_test.go: -------------------------------------------------------------------------------- 1 | package count 2 | 3 | import "testing" 4 | 5 | func TestCountTests(t *testing.T) { 6 | // ironically just running the function is enough to test it 7 | Tests(t, 1) 8 | } 9 | -------------------------------------------------------------------------------- /test/count/godoc.go: -------------------------------------------------------------------------------- 1 | // Package count is used to count the number of test cases run 2 | package count 3 | -------------------------------------------------------------------------------- /test/exists.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "embed" 5 | "testing" 6 | 7 | "github.com/lmorg/murex/test/count" 8 | ) 9 | 10 | func ExistsFs(t *testing.T, name string, res embed.FS) { 11 | t.Helper() 12 | count.Tests(t, 1) 13 | 14 | b, err := res.ReadFile(name) 15 | if err != nil { 16 | t.Errorf("Cannot read file '%s': %s", name, err.Error()) 17 | t.FailNow() 18 | } 19 | 20 | if len(b) == 0 { 21 | t.Errorf("File is empty: %s", name) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/external.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/lmorg/murex/test/count" 8 | "github.com/lmorg/murex/utils/which" 9 | ) 10 | 11 | // InstalledDepsTest checks any external dependencies are installed 12 | func InstalledDepsTest(t *testing.T, exec string) bool { 13 | t.Helper() 14 | 15 | if os.Getenv("MUREX_TEST_NO_EXEC_DEPS") != "" { 16 | return false 17 | } 18 | 19 | count.Tests(t, 1) 20 | 21 | if which.Which(exec) == "" { 22 | t.Errorf("`%s` isn't installed or not in $PATH", exec) 23 | return false 24 | } 25 | 26 | return true 27 | } 28 | -------------------------------------------------------------------------------- /test/external_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "os" 5 | "runtime" 6 | "testing" 7 | ) 8 | 9 | func TestInstalledDepsTest(t *testing.T) { 10 | if os.Getenv("MUREX_TEST_NO_EXEC_DEPS") != "" { 11 | return 12 | } 13 | 14 | var exec string 15 | 16 | switch runtime.GOOS { 17 | case "windows": 18 | exec = "cmd.exe" 19 | 20 | case "plan9": 21 | exec = "rc" 22 | 23 | default: 24 | exec = "sh" 25 | } 26 | 27 | if !InstalledDepsTest(t, exec) { 28 | t.Errorf("TestInstalledDepsTest failed") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/fd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo '[ "a", "b", "c" ]' 4 | 5 | echo json 1>&3 6 | -------------------------------------------------------------------------------- /test/file name: -------------------------------------------------------------------------------- 1 | testing files with spaces in their name -------------------------------------------------------------------------------- /test/fox.txt: -------------------------------------------------------------------------------- 1 | This is just some dummy text for regression testing 2 | the quick brown 3 | fox jumped over 4 | the lazy dog 5 | the quick 6 | brown fox 7 | jumped over 8 | the lazy 9 | dog 10 | the 11 | quick brown 12 | fox jumped 13 | over the 14 | lazy dog 15 | the 16 | quick 17 | brown 18 | fox 19 | jumped 20 | over 21 | the 22 | lazy 23 | dog -------------------------------------------------------------------------------- /test/fox_crlf.txt: -------------------------------------------------------------------------------- 1 | This is just some dummy text for regression testing 2 | the quick brown 3 | fox jumped over 4 | the lazy dog 5 | the quick 6 | brown fox 7 | jumped over 8 | the lazy 9 | dog 10 | the 11 | quick brown 12 | fox jumped 13 | over the 14 | lazy dog 15 | the 16 | quick 17 | brown 18 | fox 19 | jumped 20 | over 21 | the 22 | lazy 23 | dog 24 | -------------------------------------------------------------------------------- /test/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # To install: 4 | # ln -sv $GOPATH/src/github.com/lmorg/murex/test/pre-push .git/hooks/ 5 | 6 | cd $GOPATH/src/github.com/lmorg/murex 7 | 8 | trap ctrl_c INT 9 | 10 | ctrl_c() { 11 | printf "\n\033[0;31m[PUSH CANCELLED]\033[0m\n" 12 | exit 1 13 | } 14 | 15 | set -e 16 | 17 | echo "Running golang unit tests...." 18 | mkdir -p ./test/tmp 19 | go test ./... -race 20 | 21 | echo "Running murex behavioural tests...." 22 | go build github.com/lmorg/murex 23 | ./murex -c 'g behavioural/*.mx -> foreach f { source $f }; test run *' 24 | 25 | echo "Allowing git push to proceed...." 26 | -------------------------------------------------------------------------------- /test/source.mx: -------------------------------------------------------------------------------- 1 | out: "testing" -> null 2 | -------------------------------------------------------------------------------- /test/source.mx.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/test/source.mx.gz -------------------------------------------------------------------------------- /test/tmp/README: -------------------------------------------------------------------------------- 1 | This directory is used by some of the tests. It might not get cleared down regularly however the contents are ignored from version control 2 | -------------------------------------------------------------------------------- /test/vim.txt: -------------------------------------------------------------------------------- 1 | one 111 won 2 | two 222 too 3 | three 333 free 4 | four 444 thor 5 | fi.ve 55.55 6 | -------------------------------------------------------------------------------- /utils/README.md: -------------------------------------------------------------------------------- 1 | # utils 2 | 3 | It's pretty bad form having a generic `utils` package I know. Eventually I 4 | expect this will be tidied up better. -------------------------------------------------------------------------------- /utils/alter/splitpath.go: -------------------------------------------------------------------------------- 1 | package alter 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | ) 7 | 8 | // SplitPath takes a string with a prefixed delimiter and separates it into a slice of path elements 9 | func SplitPath(path string) ([]string, error) { 10 | split := strings.Split(path, string(path[0])) 11 | if len(split) == 0 || (len(split) == 1 && split[0] == "") { 12 | return nil, errors.New("empty path") 13 | } 14 | 15 | if split[0] == "" { 16 | split = split[1:] 17 | } 18 | 19 | return split, nil 20 | } 21 | -------------------------------------------------------------------------------- /utils/ansi/codes/godoc.go: -------------------------------------------------------------------------------- 1 | // Package codes provides common ANSI escape sequences as constants 2 | package codes 3 | -------------------------------------------------------------------------------- /utils/ansi/godoc.go: -------------------------------------------------------------------------------- 1 | // Package ansi provides APIs for writing common ANSI escape sequences to the terminal 2 | package ansi 3 | -------------------------------------------------------------------------------- /utils/ansititle/ansititle_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package ansititle 5 | 6 | func Write(title []byte) error { return nil } 7 | func Icon(title []byte) error { return nil } 8 | func Tmux(title []byte) error { return nil } 9 | -------------------------------------------------------------------------------- /utils/ansititle/ansititle_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package ansititle 5 | 6 | func Write(title []byte) error { return nil } 7 | func Icon(title []byte) error { return nil } 8 | func Tmux(title []byte) error { return nil } 9 | -------------------------------------------------------------------------------- /utils/ansititle/ansititle_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package ansititle 5 | 6 | func Write(title []byte) error { return nil } 7 | func Icon(title []byte) error { return nil } 8 | func Tmux(title []byte) error { return nil } 9 | -------------------------------------------------------------------------------- /utils/ansititle/godoc.go: -------------------------------------------------------------------------------- 1 | // Package ansititle is a little function for writing to terminal emulators title bar 2 | package ansititle 3 | -------------------------------------------------------------------------------- /utils/ansititle/write.go: -------------------------------------------------------------------------------- 1 | package ansititle 2 | 3 | import "os" 4 | 5 | func write(ansi []byte) error { 6 | if ansi == nil { 7 | return nil 8 | } 9 | 10 | _, err := os.Stdout.Write(ansi) 11 | return err 12 | } 13 | -------------------------------------------------------------------------------- /utils/cache/cachedb/lib_go.go: -------------------------------------------------------------------------------- 1 | //go:build no_cgo || linux || (windows && amd64) || darwin 2 | // +build no_cgo linux windows,amd64 darwin 3 | 4 | /* 5 | This file uses a pure Go driver for sqlite. Unlike lib_c.go, this one does 6 | not require cgo. For this reason it is the default option for custom builds 7 | however any pre-built binaries on Murex's website will be compiled against 8 | the C driver for sqlite. 9 | */ 10 | 11 | package cachedb 12 | 13 | import ( 14 | _ "modernc.org/sqlite" 15 | ) 16 | 17 | const driverName = "sqlite" 18 | -------------------------------------------------------------------------------- /utils/cache/hash.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/base64" 6 | ) 7 | 8 | func CreateHash(cmdLine string, block []rune) string { 9 | code := []byte(string(block)) 10 | toHash := append([]byte(cmdLine), code...) 11 | 12 | hash := sha256.New() 13 | _, err := hash.Write(toHash) 14 | if err != nil { 15 | return cmdLine 16 | } 17 | 18 | return base64.StdEncoding.EncodeToString(hash.Sum(nil)) 19 | } 20 | -------------------------------------------------------------------------------- /utils/cache/ttl.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import "time" 4 | 5 | func Seconds(ttl int) time.Time { 6 | return time.Now().Add(time.Duration(ttl) * time.Second) 7 | } 8 | 9 | func Days(ttl int) time.Time { 10 | return time.Now().Add(time.Duration(ttl) * time.Second * 60 * 60 * 24) 11 | } 12 | -------------------------------------------------------------------------------- /utils/cd/cache/godoc.go: -------------------------------------------------------------------------------- 1 | // Package cache preemptively walks the file system to provide faster autocompletion suggestions 2 | package cache 3 | -------------------------------------------------------------------------------- /utils/cd/cache/timeouts.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | var ( 4 | walkTimeout int = 60 5 | cacheTimeout int = 60 * 60 6 | gcSleep int = 20 * 60 7 | ) 8 | -------------------------------------------------------------------------------- /utils/cd/godoc.go: -------------------------------------------------------------------------------- 1 | // Package cd changes the current working directory and updates the global working 2 | package cd 3 | -------------------------------------------------------------------------------- /utils/consts/consts_test.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | ) 8 | 9 | // TestConsts tests the projects constants package 10 | func TestTempDir(t *testing.T) { 11 | count.Tests(t, 1) 12 | 13 | if TempDir == "" { 14 | t.Error("No temp directory specified") 15 | } 16 | 17 | if TempDir == tempDir { 18 | t.Log("ioutil.TempDir() failed so using fallback path:", tempDir) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/consts/consts_unix.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package consts 5 | 6 | const ( 7 | // PathSlash is an OS specific directory separator 8 | PathSlash = "/" 9 | 10 | // tempDir is the location of temp directory if it cannot be automatically determind 11 | tempDir = "/tmp/murex/" 12 | ) 13 | -------------------------------------------------------------------------------- /utils/consts/consts_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package consts 5 | 6 | const ( 7 | // PathSlash is an OS specific directory separator. 8 | // Normally in Windows this would be a \ but lets standardise everything in murex to be / 9 | PathSlash = "/" 10 | 11 | // tempDir is the location of temp directory if it cannot be automatically determind 12 | tempDir = `c:/temp/murex/` 13 | ) 14 | -------------------------------------------------------------------------------- /utils/consts/godoc.go: -------------------------------------------------------------------------------- 1 | // Package consts consolidates common values used throughout the source code 2 | package consts 3 | -------------------------------------------------------------------------------- /utils/counter/counter_test.go: -------------------------------------------------------------------------------- 1 | package counter 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | ) 8 | 9 | func TestCounter(t *testing.T) { 10 | count.Tests(t, 2) 11 | 12 | mc := new(MutexCounter) 13 | i := mc.Add() 14 | if i != 1 { 15 | t.Errorf("MutexCounter should eq 1: %d", i) 16 | } 17 | 18 | mc.Set(2) 19 | if !mc.NotEqual(i) { 20 | t.Errorf("MutexCounter should eq 2: %d != 2", i) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/counter/godoc.go: -------------------------------------------------------------------------------- 1 | // Package counter provides a thread safe counter using mutexes 2 | package counter 3 | -------------------------------------------------------------------------------- /utils/crash/disable.go: -------------------------------------------------------------------------------- 1 | //go:build no_crash_handler 2 | // +build no_crash_handler 3 | 4 | package crash 5 | 6 | /* 7 | We want tests to panic! 8 | 9 | So this weird source file disables the crash handler for tests 10 | */ 11 | 12 | func init() { 13 | disable_handler = true 14 | } 15 | -------------------------------------------------------------------------------- /utils/dedup/godoc.go: -------------------------------------------------------------------------------- 1 | // Package dedup provides de-duplication routines 2 | package dedup 3 | -------------------------------------------------------------------------------- /utils/docgen/api/godoc.go: -------------------------------------------------------------------------------- 1 | // Package docgen contains all the executing code of the docgen CLI but in API form 2 | package docgen 3 | -------------------------------------------------------------------------------- /utils/docgen/api/templates.go: -------------------------------------------------------------------------------- 1 | package docgen 2 | 3 | import "text/template" 4 | 5 | func readTemplate(path string) *template.Template { 6 | if path == "" { 7 | return nil 8 | } 9 | 10 | f := fileReader(path) 11 | tmpl := string(readAll(f)) 12 | return template.Must(template.New(path).Funcs(funcMap).Parse(tmpl)) 13 | } 14 | -------------------------------------------------------------------------------- /utils/docgen/api/unmarshaller.go: -------------------------------------------------------------------------------- 1 | package docgen 2 | 3 | import ( 4 | "fmt" 5 | 6 | yaml "gopkg.in/yaml.v3" 7 | ) 8 | 9 | func parseSourceFile(path string, structure interface{}) { 10 | f := fileReader(path) 11 | yml := yaml.NewDecoder(f) 12 | yml.KnownFields(true) 13 | err := yml.Decode(structure) 14 | if err != nil { 15 | panic(fmt.Sprintf("%s (%s)", err.Error(), path)) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/docgen/godoc.go: -------------------------------------------------------------------------------- 1 | // docgen is a tool for auto-generating technical documents 2 | // 3 | // The purpose of this tool is to automate documentation as much as possible 4 | // and have the output a static CMS which can be hosted on GitHub or S3 5 | // (depending on whether your templates are markdown or HTML). 6 | // 7 | // This project is designed to be run independently from murex and at some 8 | // point it will be separated into it's own git repository (at a stage when I 9 | // am confident that murex will no longer be the primary driver for features, 10 | // bugs or other code changes) 11 | 12 | package main 13 | -------------------------------------------------------------------------------- /utils/envvars/godoc.go: -------------------------------------------------------------------------------- 1 | // Package envvars provides a more pleasant framework around Go's stdlibs for working with environmental variables 2 | package envvars 3 | -------------------------------------------------------------------------------- /utils/escape/godoc.go: -------------------------------------------------------------------------------- 1 | // Package escape provides tools for escaping command line snippets of code 2 | package escape 3 | -------------------------------------------------------------------------------- /utils/exists.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "os" 4 | 5 | func Exists(path string) bool { 6 | if _, err := os.Stat(path); os.IsNotExist(err) { 7 | return false 8 | } 9 | 10 | return true 11 | } 12 | -------------------------------------------------------------------------------- /utils/exists_test.go: -------------------------------------------------------------------------------- 1 | package utils_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | "github.com/lmorg/murex/utils" 8 | ) 9 | 10 | func TestExists(t *testing.T) { 11 | count.Tests(t, 2) 12 | 13 | if !utils.Exists("README.md") { 14 | t.Error(`Exists("README.md") == false when it should have been true`) 15 | } 16 | 17 | if utils.Exists("lkjdslksdjflsdkjflsdkjflsdkfjsldkjfds") { 18 | t.Error(`Exists("lkjdslksdjflsdkjflsdkjflsdkfjsldkjfds") == true when it should have been false`) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/home/godoc.go: -------------------------------------------------------------------------------- 1 | // Package home is used to return the users home directory 2 | package home 3 | -------------------------------------------------------------------------------- /utils/home/home.go: -------------------------------------------------------------------------------- 1 | //go:build !js 2 | // +build !js 3 | 4 | package home 5 | 6 | import ( 7 | "os" 8 | "os/user" 9 | 10 | "github.com/lmorg/murex/utils" 11 | "github.com/lmorg/murex/utils/consts" 12 | ) 13 | 14 | // MyDir is the $USER directory. 15 | // Typically /home/$USER/ on non-Windows systems, or \users\$USER on Windows. 16 | var MyDir string 17 | 18 | func init() { 19 | usr, err := user.Current() 20 | if err != nil { 21 | os.Stderr.WriteString(err.Error() + utils.NewLineString) 22 | MyDir = consts.PathSlash 23 | return 24 | } 25 | 26 | MyDir = usr.HomeDir 27 | } 28 | -------------------------------------------------------------------------------- /utils/home/home_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package home 5 | 6 | // MyDir is the $USER directory. 7 | var MyDir = "/" 8 | 9 | // UserDir is the home directory of a `username`. 10 | func UserDir(_ string) string { 11 | return "/" 12 | } 13 | -------------------------------------------------------------------------------- /utils/home/home_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package home 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/lmorg/murex/test/count" 10 | ) 11 | 12 | // TestMyHome tests your home directory can be derived 13 | func TestMyHome(t *testing.T) { 14 | count.Tests(t, 1) 15 | if MyDir == "" { 16 | t.Error("MyDir not set (murex will still function)") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/humannumbers/columnletter.go: -------------------------------------------------------------------------------- 1 | package humannumbers 2 | 3 | // ColumnLetter takes an int and converts it to an Excel-style column letter 4 | // reference (eg `C` or `AB`) 5 | func ColumnLetter(i int) string { 6 | var col string 7 | 8 | for i >= 0 { 9 | mod := i % 26 10 | col = string([]byte{byte(mod) + 65}) + col 11 | i = ((i - mod) / 26) - 1 12 | } 13 | 14 | return col 15 | } 16 | -------------------------------------------------------------------------------- /utils/humannumbers/godoc.go: -------------------------------------------------------------------------------- 1 | // Package humannumbers is used to return human readable representations of numbers 2 | package humannumbers 3 | -------------------------------------------------------------------------------- /utils/humannumbers/ordinal.go: -------------------------------------------------------------------------------- 1 | package humannumbers 2 | 3 | import "strconv" 4 | 5 | // Ordinal returns the number + ordinal suffix 6 | func Ordinal(i int) string { 7 | s := strconv.Itoa(i) 8 | 9 | switch i % 100 { 10 | case 11, -11, 12, -12: 11 | return s + "th" 12 | } 13 | 14 | switch i % 10 { 15 | case 1, -1: 16 | return s + "st" 17 | case 2, -2: 18 | return s + "nd" 19 | case 3, -3: 20 | return s + "rd" 21 | default: 22 | return s + "th" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /utils/inject/godoc.go: -------------------------------------------------------------------------------- 1 | // Package inject is used to insert one string inside another 2 | package inject 3 | -------------------------------------------------------------------------------- /utils/json/godoc.go: -------------------------------------------------------------------------------- 1 | // Package json is a custom json parser with an aim to provide more descriptive errors when reading malformed json 2 | package json 3 | -------------------------------------------------------------------------------- /utils/json/lazy.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import "encoding/json" 4 | 5 | func LazyLogging(v interface{}) string { 6 | b, _ := json.Marshal(v) 7 | return string(b) 8 | } 9 | 10 | func LazyLoggingPretty(v interface{}) string { 11 | b, _ := json.MarshalIndent(v, "", " ") 12 | return string(b) 13 | } 14 | -------------------------------------------------------------------------------- /utils/json/lazy_test.go: -------------------------------------------------------------------------------- 1 | package json_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | "github.com/lmorg/murex/utils/json" 8 | ) 9 | 10 | func TestLazyLogging(t *testing.T) { 11 | count.Tests(t, 3) 12 | 13 | act := json.LazyLogging(nil) 14 | if act != "null" { 15 | t.Errorf("Actual != 'null': %s", act) 16 | } 17 | 18 | act = json.LazyLogging(3) 19 | if act != "3" { 20 | t.Errorf("Actual != 3 : %s", act) 21 | } 22 | 23 | act = json.LazyLogging("foobar") 24 | if act != `"foobar"` { 25 | t.Errorf(`Actual != '"foobar"' : %s`, act) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/json/unmarshal_fuzz_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package json 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/lmorg/murex/test/count" 10 | ) 11 | 12 | func FuzzParser(f *testing.F) { 13 | tests := []string{``, "[\n 1,\n 2,\n 3\n]", `{ "key: "#value" }`, `{ "key": ({ value }) }`} 14 | for _, tc := range tests { 15 | f.Add(tc) // Use f.Add to provide a seed corpus 16 | } 17 | f.Fuzz(func(t *testing.T, data string) { 18 | count.Tests(t, 1) 19 | unmarshalMurex([]byte(data), nil) 20 | // we are just testing we can't cause an unhandled panic 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /utils/lists/crop.go: -------------------------------------------------------------------------------- 1 | package lists 2 | 3 | import "strings" 4 | 5 | func CropPartial(list []string, partial string) []string { 6 | var items []string 7 | for i := range list { 8 | if strings.HasPrefix(list[i], partial) { 9 | items = append(items, list[i][len(partial):]) 10 | } 11 | } 12 | 13 | return items 14 | } 15 | 16 | func CropPartialMapKeys(m map[string]string, partial string) map[string]string { 17 | cropped := make(map[string]string) 18 | for key, val := range m { 19 | if strings.HasPrefix(key, partial) { 20 | cropped[key[len(partial):]] = val 21 | } 22 | } 23 | 24 | return cropped 25 | } 26 | -------------------------------------------------------------------------------- /utils/lists/godoc.go: -------------------------------------------------------------------------------- 1 | // Package lists provides standard APIs for handling lists 2 | package lists 3 | -------------------------------------------------------------------------------- /utils/lists/match.go: -------------------------------------------------------------------------------- 1 | package lists 2 | 3 | func Match(a []string, s string) bool { 4 | for i := range a { 5 | if a[i] == s { 6 | return true 7 | } 8 | } 9 | 10 | return false 11 | } 12 | -------------------------------------------------------------------------------- /utils/lists/match_test.go: -------------------------------------------------------------------------------- 1 | package lists_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | "github.com/lmorg/murex/utils/lists" 8 | ) 9 | 10 | func TestMatch(t *testing.T) { 11 | count.Tests(t, 3) 12 | 13 | a := []string{"foo", "bar"} 14 | 15 | if !lists.Match(a, "foo") { 16 | t.Error("Did not match foo") 17 | } 18 | 19 | if !lists.Match(a, "bar") { 20 | t.Error("Did not match bar") 21 | } 22 | 23 | if lists.Match(a, "foobar") { 24 | t.Error("Incorrectly matched foobar") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /utils/man/descriptions_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package man 5 | 6 | import "fmt" 7 | 8 | var manBlock = `man $command` 9 | 10 | func ManPageExecBlock(width int) []rune { 11 | return []rune(fmt.Sprintf(manBlock, width)) 12 | } 13 | -------------------------------------------------------------------------------- /utils/man/descriptions_unix.go: -------------------------------------------------------------------------------- 1 | //go:build !linux && !windows 2 | // +build !linux,!windows 3 | 4 | package man 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | var manBlock = []rune(` 11 | trypipe { 12 | /usr/bin/zcat -f ${man -w $command} -> mandoc -O width=%d -c 13 | } 14 | catch { 15 | man $command 16 | }`) 17 | 18 | func ManPageExecBlock(width int) []rune { 19 | return []rune(fmt.Sprintf(string(manBlock), width, width)) 20 | } 21 | -------------------------------------------------------------------------------- /utils/man/flags_cache.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package man 5 | 6 | type flagsT struct { 7 | Flags []string 8 | Descriptions map[string]string 9 | } 10 | -------------------------------------------------------------------------------- /utils/man/godoc.go: -------------------------------------------------------------------------------- 1 | // Package man is murex's man page parser to provide flag auto-complete suggestions 2 | package man 3 | -------------------------------------------------------------------------------- /utils/man/man_windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package man 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | // TestMan tests the builtins package 11 | func TestMan(t *testing.T) { 12 | t.Skip("Not used on Windows") 13 | } 14 | -------------------------------------------------------------------------------- /utils/man/test_cat.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_cat.1.gz -------------------------------------------------------------------------------- /utils/man/test_cp.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_cp.1.gz -------------------------------------------------------------------------------- /utils/man/test_find.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_find.1.gz -------------------------------------------------------------------------------- /utils/man/test_git-commit.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_git-commit.1.gz -------------------------------------------------------------------------------- /utils/man/test_ls.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_ls.1.gz -------------------------------------------------------------------------------- /utils/man/test_ssh.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmorg/murex/b4c429617fd41527ea0efef33c52c15ef2b64972/utils/man/test_ssh.1.gz -------------------------------------------------------------------------------- /utils/mxjson/godoc.go: -------------------------------------------------------------------------------- 1 | // Package mxjson is a custom json superset format used by some routines in murex 2 | package mxjson 3 | -------------------------------------------------------------------------------- /utils/mxjson/testdata/fuzz/FuzzParser/82028ed5c60310bba0f811c32cc8524ce8b953755e4d634e79719f65438cb2c5: -------------------------------------------------------------------------------- 1 | go test fuzz v1 2 | string("{{}{}}0 ") 3 | -------------------------------------------------------------------------------- /utils/parser/godoc.go: -------------------------------------------------------------------------------- 1 | // Package parser is a faster murex parser for real time context hints 2 | package parser 3 | -------------------------------------------------------------------------------- /utils/parser/pipetoken_test.go: -------------------------------------------------------------------------------- 1 | package parser_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/lmorg/murex/test/count" 7 | "github.com/lmorg/murex/utils/parser" 8 | ) 9 | 10 | func TestPipeTokenString(t *testing.T) { 11 | count.Tests(t, 2) 12 | 13 | var pt parser.ParsedTokens 14 | 15 | if pt.PipeToken.String() != "PipeTokenNone" { 16 | t.Errorf("Missing stringer definitions") 17 | } 18 | 19 | pt.PipeToken = 99 20 | if pt.PipeToken.String() != "PipeToken(99)" { 21 | t.Errorf("Possibly hardcoded stringer definitions?") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /utils/parser/safe_test.go: -------------------------------------------------------------------------------- 1 | package parser_test 2 | 3 | import ( 4 | "testing" 5 | 6 | _ "github.com/lmorg/murex/builtins" 7 | "github.com/lmorg/murex/lang" 8 | "github.com/lmorg/murex/test/count" 9 | "github.com/lmorg/murex/utils/parser" 10 | ) 11 | 12 | func TestIsSafeCmdsBuiltins(t *testing.T) { 13 | safeCmdsLocal := parser.GetSafeCmds() 14 | 15 | count.Tests(t, len(safeCmdsLocal)) 16 | 17 | for _, cmd := range safeCmdsLocal { 18 | if lang.GoFunctions[cmd] == nil { 19 | t.Errorf("Command hardcoded in safe whitelist but is not a builtin: %s", cmd) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/path/join.go: -------------------------------------------------------------------------------- 1 | package path 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | 7 | "github.com/lmorg/murex/utils/consts" 8 | ) 9 | 10 | func Join(a []string) (s string) { 11 | switch { 12 | case len(a) == 0: 13 | return consts.PathSlash 14 | 15 | case a[0] == consts.PathSlash: 16 | s = strings.Join(a[1:], consts.PathSlash) 17 | s = consts.PathSlash + s 18 | 19 | default: 20 | s = strings.Join(a, consts.PathSlash) 21 | } 22 | 23 | if s != consts.PathSlash { 24 | if f, _ := os.Stat(s); f != nil && f.IsDir() { 25 | s += consts.PathSlash 26 | } 27 | } 28 | return s 29 | } 30 | -------------------------------------------------------------------------------- /utils/path/split.go: -------------------------------------------------------------------------------- 1 | package path 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | 7 | "github.com/lmorg/murex/utils/consts" 8 | ) 9 | 10 | func Split(s string) []string { 11 | if len(s) == 0 { 12 | return []string{"."} 13 | } 14 | 15 | s = path.Clean(s) 16 | 17 | split := strings.Split(s, consts.PathSlash) 18 | 19 | if len(split) == 0 { 20 | // this should never happen 21 | return []string{"."} 22 | } 23 | 24 | if len(split) > 0 && split[0] == "" { 25 | split[0] = consts.PathSlash 26 | } 27 | 28 | if split[len(split)-1] == "" { 29 | split = split[:len(split)-1] 30 | } 31 | 32 | return split 33 | } 34 | -------------------------------------------------------------------------------- /utils/pathsplit/godoc.go: -------------------------------------------------------------------------------- 1 | // Package pathsplit is a standard API for splitting a path by the first character in the path 2 | package pathsplit 3 | -------------------------------------------------------------------------------- /utils/pathsplit/pathsplit.go: -------------------------------------------------------------------------------- 1 | package pathsplit 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | ) 7 | 8 | func Split(path string) ([]string, error) { 9 | switch len(path) { 10 | case 0: 11 | return nil, errors.New("empty path and missing separator") 12 | 13 | case 1: 14 | return nil, errors.New("path separator supplied but empty path followed") 15 | 16 | case 2: 17 | if path[0] == path[1] { 18 | return []string{""}, nil 19 | } 20 | fallthrough 21 | 22 | default: 23 | return strings.Split(path[1:], path[0:1]), nil 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /utils/posix.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package utils 5 | 6 | var ( 7 | // NewLineByte is a new line in POSIX systems (no carriage return) as []byte's 8 | NewLineByte []byte = []byte{'\n'} 9 | // NewLineString is a new line in POSIX systems (no carriage return) as a string 10 | NewLineString string = "\n" 11 | ) 12 | -------------------------------------------------------------------------------- /utils/posix/godoc.go: -------------------------------------------------------------------------------- 1 | // Package posix is a quick helper function to determine if the running platform is POSIX or not 2 | package posix 3 | -------------------------------------------------------------------------------- /utils/posix/posix.go: -------------------------------------------------------------------------------- 1 | package posix 2 | 3 | import "runtime" 4 | 5 | // IsPosix returns `true` when running on a POSIX host 6 | func IsPosix() bool { 7 | return isPosix(runtime.GOOS) 8 | } 9 | 10 | func isPosix(os string) bool { 11 | return os != "windows" && os != "plan9" 12 | } 13 | -------------------------------------------------------------------------------- /utils/readall/godoc.go: -------------------------------------------------------------------------------- 1 | // Package readall provides an alterative to ioutil.Readall but with support for context.Context 2 | package readall 3 | -------------------------------------------------------------------------------- /utils/readline/editor_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package readline 5 | 6 | import "errors" 7 | 8 | func (rl *Instance) launchEditor(multiline []rune) ([]rune, error) { 9 | return rl.line.Runes(), errors.New("Not currently supported in WebAssembly") 10 | } 11 | -------------------------------------------------------------------------------- /utils/readline/editor_plan9.go: -------------------------------------------------------------------------------- 1 | //go:build plan9 2 | // +build plan9 3 | 4 | package readline 5 | 6 | import "errors" 7 | 8 | func (rl *Instance) launchEditor(multiline []rune) ([]rune, error) { 9 | return rl.line.Runes(), errors.New("Not currently supported on Plan 9") 10 | } 11 | -------------------------------------------------------------------------------- /utils/readline/editor_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package readline 5 | 6 | import "errors" 7 | 8 | func (rl *Instance) launchEditor(multiline []rune) ([]rune, error) { 9 | return rl.line.Runes(), errors.New("Not currently supported on Windows") 10 | } 11 | -------------------------------------------------------------------------------- /utils/readline/errors.go: -------------------------------------------------------------------------------- 1 | package readline 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | const ( 8 | _CtrlC = "Ctrl+C" 9 | _EOF = "EOF" 10 | ) 11 | 12 | var ( 13 | // CtrlC is returned when ctrl+c is pressed 14 | ErrCtrlC = errors.New(_CtrlC) 15 | 16 | // EOF is returned when ctrl+d is pressed. 17 | // (this is actually the same value as io.EOF) 18 | ErrEOF = errors.New(_EOF) 19 | ) 20 | -------------------------------------------------------------------------------- /utils/readline/godoc.go: -------------------------------------------------------------------------------- 1 | // Package readline is a pure-Go re-imagining of the UNIX readline API 2 | package readline 3 | -------------------------------------------------------------------------------- /utils/readline/raw_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build darwin || dragonfly || freebsd || netbsd || openbsd 6 | // +build darwin dragonfly freebsd netbsd openbsd 7 | 8 | package readline 9 | 10 | import "golang.org/x/sys/unix" 11 | 12 | const ioctlReadTermios = unix.TIOCGETA 13 | const ioctlWriteTermios = unix.TIOCSETA 14 | 15 | //const OXTABS = unix.OXTABS 16 | -------------------------------------------------------------------------------- /utils/readline/raw_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build linux 6 | // +build linux 7 | 8 | package readline 9 | 10 | import "golang.org/x/sys/unix" 11 | 12 | const ioctlReadTermios = unix.TCGETS 13 | const ioctlWriteTermios = unix.TCSETS 14 | 15 | //const OXTABS = unix.XTABS 16 | -------------------------------------------------------------------------------- /utils/readline/read.go: -------------------------------------------------------------------------------- 1 | package readline 2 | 3 | func removeNonPrintableChars(s []byte) int { 4 | var ( 5 | i int 6 | next int 7 | ) 8 | 9 | for next = 0; next < len(s); next++ { 10 | if s[next] < ' ' && s[next] != charEOF && s[next] != charEscape && 11 | s[next] != charTab && s[next] != charBackspace { 12 | 13 | continue 14 | 15 | } else { 16 | s[i] = s[next] 17 | i++ 18 | } 19 | } 20 | 21 | return i 22 | } 23 | -------------------------------------------------------------------------------- /utils/readline/read_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package readline 5 | 6 | import ( 7 | "errors" 8 | ) 9 | 10 | var Stdin = make(chan string, 0) 11 | 12 | func read(b []byte) (int, error) { 13 | stdin := <-Stdin 14 | 15 | if len(stdin) > len(b) { 16 | return 0, errors.New("wasm keystrokes > b (this is a bug)") 17 | } 18 | 19 | for i := range stdin { 20 | b[i] = stdin[i] 21 | } 22 | 23 | return len(stdin), nil 24 | } 25 | -------------------------------------------------------------------------------- /utils/readline/read_tty.go: -------------------------------------------------------------------------------- 1 | //go:build !js 2 | // +build !js 3 | 4 | package readline 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/lmorg/murex/debug" 11 | ) 12 | 13 | func read(b []byte) (int, error) { 14 | i, err := os.Stdin.Read(b) 15 | 16 | if err != nil && debug.Enabled { 17 | s := fmt.Sprintf("!!! cannot read from stdin: %s", err.Error()) 18 | debug.Log(s) 19 | panic(s) 20 | } 21 | 22 | return i, err 23 | } 24 | -------------------------------------------------------------------------------- /utils/readline/signal_fallback.go: -------------------------------------------------------------------------------- 1 | //go:build windows || js || plan9 2 | // +build windows js plan9 3 | 4 | package readline 5 | 6 | func (rl *Instance) sigwinch() { 7 | rl.closeSigwinch = func() { 8 | // empty function because SIGWINCH isn't supported on these platforms 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/readline/syntax.go: -------------------------------------------------------------------------------- 1 | package readline 2 | 3 | func (rl *Instance) syntaxCompletion() { 4 | if rl.SyntaxCompleter == nil { 5 | return 6 | } 7 | 8 | newLine, newPos := rl.SyntaxCompleter(rl.line.Runes(), rl.lineChange, rl.line.RunePos()-1) 9 | if string(newLine) == rl.line.String() { 10 | return 11 | } 12 | 13 | newPos++ 14 | 15 | rl.line.Set(rl, newLine) 16 | rl.line.SetRunePos(newPos) 17 | } 18 | -------------------------------------------------------------------------------- /utils/readline/term.go: -------------------------------------------------------------------------------- 1 | package readline 2 | 3 | import "os" 4 | 5 | // GetTermWidth returns the width of Stdout or 80 if the width cannot be established 6 | func GetTermWidth() (termWidth int) { 7 | var err error 8 | fd := int(os.Stdout.Fd()) 9 | termWidth, _, err = GetSize(fd) 10 | if err != nil { 11 | termWidth = 80 // default to 80 with term width unknown as that is the de factor standard on older terms. 12 | } 13 | 14 | return 15 | } 16 | -------------------------------------------------------------------------------- /utils/readline/write_js.go: -------------------------------------------------------------------------------- 1 | //go:build js 2 | // +build js 3 | 4 | package readline 5 | 6 | import "syscall/js" 7 | 8 | func print(s string) { 9 | vtermWrite([]rune(s)) 10 | } 11 | 12 | func printErr(s string) { 13 | vtermWrite([]rune(s)) 14 | } 15 | 16 | func vtermWrite(r []rune) { 17 | VTerm.Write(r) 18 | 19 | //divMutex.Lock() 20 | 21 | html := VTerm.ExportHtml() 22 | 23 | jsDoc := js.Global().Get("document") 24 | outElement := jsDoc.Call("getElementById", "term") 25 | outElement.Set("innerHTML", html) 26 | 27 | //divMutex.Unlock() 28 | } 29 | -------------------------------------------------------------------------------- /utils/readline/write_tty.go: -------------------------------------------------------------------------------- 1 | //go:build !js 2 | // +build !js 3 | 4 | package readline 5 | 6 | import "os" 7 | 8 | func print(s string) { 9 | os.Stdout.WriteString(s) 10 | } 11 | 12 | func printErr(s string) { 13 | os.Stderr.WriteString(s) 14 | } 15 | -------------------------------------------------------------------------------- /utils/rmbs/rmbs.go: -------------------------------------------------------------------------------- 1 | package rmbs 2 | 3 | // Remove back spaces from a string 4 | func Remove(s string) string { 5 | r := []rune(s) 6 | //l := len(r) 7 | p := 0 8 | 9 | for i := range r { 10 | if r[i] == 8 && p > 0 { 11 | p-- 12 | continue 13 | } 14 | r[p] = r[i] 15 | p++ 16 | } 17 | 18 | return string(r[:p]) 19 | } 20 | -------------------------------------------------------------------------------- /utils/spellcheck/godoc.go: -------------------------------------------------------------------------------- 1 | // Package spellcheck provides functions for spellchecking 2 | package spellcheck 3 | -------------------------------------------------------------------------------- /utils/spellcheck/userdictionary/godoc.go: -------------------------------------------------------------------------------- 1 | // Package userdictionary provides `config` hooks for the spellchecker user dictionary 2 | package userdictionary 3 | -------------------------------------------------------------------------------- /utils/url.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "regexp" 4 | 5 | var rxUrl *regexp.Regexp = regexp.MustCompile(`(?i)^http(s)?://`) 6 | 7 | // IsURL checks the start of a string to see if it has a valid HTTP protocol 8 | func IsURL(url string) bool { 9 | return rxUrl.MatchString(url) 10 | } 11 | -------------------------------------------------------------------------------- /utils/virtualterm/godoc.go: -------------------------------------------------------------------------------- 1 | // Package virtualterm provides a virtual terminal and some terminal emulation functions 2 | package virtualterm 3 | -------------------------------------------------------------------------------- /utils/wasmserver/godoc.go: -------------------------------------------------------------------------------- 1 | // Package main provides a web server for user acceptance testing of js/wasm builds 2 | package main 3 | -------------------------------------------------------------------------------- /utils/wasmserver/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /*func TestGoPath(t *testing.T) { 4 | count.Tests(t, 1) 5 | 6 | pwd := goPath() 7 | 8 | if pwd == "" { 9 | t.Error("$GOPATH env var appears to be unset. This is needed for wasmserver to locate which directory to serve") 10 | } 11 | }*/ 12 | 13 | /*func TestPathBuilder(t *testing.T) { 14 | count.Tests(t, 1) 15 | 16 | test.Exists(t, pathBuilder()+"/index.html") 17 | }*/ 18 | -------------------------------------------------------------------------------- /utils/which/godoc.go: -------------------------------------------------------------------------------- 1 | // Package which provides similar functionality to the UNIX command of the same name 2 | package which 3 | -------------------------------------------------------------------------------- /utils/which/path.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package which 5 | 6 | import "strings" 7 | 8 | // SplitPath takes a $PATH (or similar) string and splits it into an array of paths 9 | func SplitPath(envPath string) []string { 10 | split := strings.Split(envPath, ":") 11 | return split 12 | } 13 | -------------------------------------------------------------------------------- /utils/which/path_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package which 5 | 6 | import "strings" 7 | 8 | // SplitPath takes a %PATH% (or similar) string and splits it into an array of paths 9 | func SplitPath(envPath string) []string { 10 | split := strings.Split(envPath, ";") 11 | return split 12 | } 13 | -------------------------------------------------------------------------------- /utils/windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package utils 5 | 6 | var ( 7 | // NewLineByte is a new line in Windows (carriage return, line feed) as []byte's 8 | NewLineByte []byte = []byte{'\r', '\n'} 9 | // NewLineString is a new line in Windows (carriage return, line feed) as a string 10 | NewLineString string = "\r\n" 11 | ) 12 | --------------------------------------------------------------------------------