Giter Site home page Giter Site logo

optex's Introduction

NAME

optex - General purpose command option wrapper

VERSION

Version 1.00

SYNOPSIS

optex command [ -Mmodule ] ...

or command -> optex symlink, or

optex options [ -l | -m ] ...

--link,   --ln  create symlink
--unlink, --rm  remove symlink
--ls            list link files
--rc            list rc files
--nop, -x       disable option processing
--[no]module    disable module option on arguments

DESCRIPTION

optex is a general purpose command option handling wrapper utilizing Perl module Getopt::EX. It enables user to define their own option aliases for any commands on the system, and provide module style extensibility.

Target command is given as an argument:

% optex command

or as a symbolic linked file to optex:

command -> optex

If the configuration file ~/.optex.d/command.rc exists, it is evaluated before execution and command arguments are pre-processed using it.

OPTION ALIASES

Think of macOS's date command, which does not have -I[TIMESPEC] option. Using optex, these can be implemented by preparing following setting in ~/.optex.d/date.rc file.

option -I        -Idate
option -Idate    +%F
option -Iseconds +%FT%T%z
option -Iminutes +%FT%H:%M%z
option -Ihours   +%FT%H%z

option --iso-8601         -I
option --iso-8601=date    -Idate
option --iso-8601=seconds -Iseconds
option --iso-8601=minutes -Iminutes
option --iso-8601=hours   -Ihours

Then next command will work as expected.

% optex date -Iseconds

If a symbolic link date -> optex is found in command search path, you can use it just same as standard command, but with unsupported options.

% date -Iseconds

Common configuration is stored in ~/.optex.d/default.rc file, and those rules are applied to all commands executed through optex.

Actually, --iso-8601 option can be defined simpler as this:

option --iso-8601 -I$<shift>

This works fine almost always, but fails with sole --iso-8601 option preceding other option like this:

% date --iso-8601 -u

COMMAND ALIASES

Command aliases can be set in the configuration file like this:

[alias]
    pgrep = [ "greple", "-Mperl", "--code" ]

Alias name is used to find rc file and module directory. In the above example, ~/.optex.d/pgrep.rc and ~/.optex.d/pgrep/ will be referred.

Read "CONFIGURATION FILE" section.

MACROS

Complex string can be composed using macro define. Next example is an awk script to count vowels in the text, to be declared in file ~/.optex.d/awk.rc.

define __delete__ /[bcdfgkmnpsrtvwyz]e( |$)/
define __match__  /ey|y[aeiou]*|[aeiou]+/
define __count_vowels__ <<EOS
{
    s = tolower($0);
    gsub(__delete__, " ", s);
    for (count=0; match(s, __match__); count++) {
        s=substr(s, RSTART + RLENGTH);
    }
    print count " " $0;
}
EOS
option --vowels __count_vowels__

This can be used like this:

% awk --vowels /usr/share/dict/words

When setting complex option, expand directive is useful. expand works almost same as option, but effective only within the file scope, and not available for command line option.

expand repository   ( -name .git -o -name .svn -o -name RCS )
expand no_dots      ! -name .*
expand no_version   ! -name *,v
expand no_backup    ! -name *~
expand no_image     ! -iname *.jpg  ! -iname *.jpeg \
                    ! -iname *.gif  ! -iname *.png
expand no_archive   ! -iname *.tar  ! -iname *.tbz  ! -iname *.tgz
expand no_pdf       ! -iname *.pdf

option --clean \
        repository -prune -o \
        -type f \
        no_dots \
        no_version no_backup \
        no_image \
        no_archive \
        no_pdf

% find . --clean -print

MODULES

optex also supports module extension. In the example of date, module file is found at ~/.optex.d/date/ directory. If default module, ~/.optex.d/date/default.pm exists, it is loaded automatically on every execution.

This is a normal Perl module, so package declaration and the final true value is necessary. Between them, you can put any kind of Perl code. For example, next program set environment variable LANG to C before executing date command.

package default;
$ENV{LANG} = 'C';
1;

% /bin/date
2017年 10月22日 日曜日 18時00分00秒 JST

% date
Sun Oct 22 18:00:00 JST 2017

Other modules are loaded using -M option. Unlike other options, -M have to be placed at the beginning of argument list. Module files in ~/.optex.d/date/ directory are used only for date command. If the module is placed on ~/.optex.d/ directory, it can be used from all commands.

If you want use -Mes module, make a file ~/.optex.d/es.pm with following content.

package es;
$ENV{LANG} = 'es_ES';
1;

% date -Mes
domingo, 22 de octubre de 2017, 18:00:00 JST

When the specified module was not found in library path, optex ignores the option and stops argument processing immediately. Ignored options are passed through to the target command.

Module is also used with subroutine call. Suppose ~/.optex.d/env.pm module look like:

package env;
sub setenv {
    while (($a, $b) = splice @_, 0, 2) {
        $ENV{$a} = $b;
    }
}
1;

Then it can be used in more generic fashion. In the next example, first format is easy to read, but second one is more easy to type because it does not have special characters to be escaped.

% date -Menv::setenv(LANG=de_DE) # need shell quote
% date -Menv::setenv=LANG=de_DE  # alternative format
So 22 Okt 2017 18:00:00 JST

Option aliases can be also declared in the module, at the end of file, following special literal __DATA__. Using this, you can prepare multiple set of options for different purposes. Think about generic i18n module:

package i18n;
1;
__DATA__
option --cn -Menv::setenv(LANG=zh_CN) // **語 - 簡体字
option --tw -Menv::setenv(LANG=zh_TW) // **語 - 繁体字
option --us -Menv::setenv(LANG=en_US) // 英語
option --fr -Menv::setenv(LANG=fr_FR) // フランス語
option --de -Menv::setenv(LANG=de_DE) // ドイツ語
option --it -Menv::setenv(LANG=it_IT) // イタリア語
option --jp -Menv::setenv(LANG=ja_JP) // 日本語
option --kr -Menv::setenv(LANG=ko_KR) // 韓国語
option --br -Menv::setenv(LANG=pt_BR) // ポルトガル語 - ブラジル
option --es -Menv::setenv(LANG=es_ES) // スペイン語
option --ru -Menv::setenv(LANG=ru_RU) // ロシア語

This can be used like:

% date -Mi18n --tw
2017年10月22日 週日 18時00分00秒 JST

You can declare autoload module in your ~/.optex.d/optex.rc like:

autoload -Mi18n --cn --tw --us --fr --de --it --jp --kr --br --es --ru

Then you can use them without module option. In this case, option --ru is replaced by -Mi18n --ru automatically.

% date --ru
воскресенье, 22 октября 2017 г. 18:00:00 (JST)

Module i18n is implemented as Getopt::EX::i18n and included in this distribution. So it can be used as above without additional installation.

STANDARD MODULES

Standard modules are installed at App::optex, and they can be addressed with and without App::optex prefix.

  • -Mhelp

    Print available option list. Option name is printed with substitution form, or help message if defined. Use -x option to omit help message.

    Option --man or -h will print document if available. Option -l will print module path. Option -m will show the module itself. When used after other modules, print information about the last declared module. Next command show the document about second module.

      optex -Mfirst -Msecond -Mhelp --man
    
  • -Mdebug

    Print debug messages.

  • -Mutil::argv

    Module to manipulate command argument. See App::optex::util::argv for detail.

  • -Mutil::filter

    Module to implement command input/output filters. See App::optex::util::filter for detail.

Getopt::EX MODULES

In addition to its own modules, optex can also use Getopt::EX modules. The standard Getopt::EX modules installed are these.

  • -Mi18n (Getopt::EX::i18n)

    You can display a Greek calendar by doing the following:

      optex -Mi18n cal --gr
    

OPTIONS

These options are not effective when optex was executed from symbolic link.

  • --link, --ln [ command ]

    Create symbolic link in ~/.optex.d/bin directory.

  • --unlink, --rm [ -f ] [ command ]

    Remove symbolic link in ~/.optex.d/bin directory.

  • --ls [ -l ] [ command ]

    List symbolic link files in ~/.optex.d/bin directory.

  • --rc [ -l ] [ -m ] [ command ]

    List rc files in ~/.optex.d directory.

  • --nop, -x command

    Stop option manipulation. Use full pathname otherwise.

  • --[no]module

    optex deals with module option (-M) on target command by default. However, there is a command which also uses same option for own purpose. Option --nomodule disables that behavior. Other option interpretation is still effective, and there is no problem using module option in rc or module files.

  • --exit status

    Usually optex exits with status of executed command. This option override it and force to exit with specified status code.

CONFIGURATION FILE

When starting up, optex reads configuration file ~/.optex.d/config.toml which is supposed to be written in TOML format.

PARAMETERS

  • no-module

    Set commands for which optex does not interpret module option -M. If the target command is found in this list, it is executed as if option --no-module is given to optex.

      no-module = [
          "greple",
          "pgrep",
      ]
    
  • alias

    Set command aliases. Example:

      [alias]
          pgrep = [ "greple", "-Mperl", "--code" ]
          hello = "echo -n 'hello world!'"
    

    Command alias can be invoked either from symbolic link and command argument.

FILES AND DIRECTORIES

  • PERLLIB/App/optex

    System module directory.

  • ~/.optex.d/

    Personal root directory.

  • ~/.optex.d/config.toml

    Configuration file.

  • ~/.optex.d/default.rc

    Common startup file.

  • ~/.optex.d/command.rc

    Startup file for command.

  • ~/.optex.d/command/

    Module directory for command.

  • ~/.optex.d/command/default.pm

    Default module for command.

  • ~/.optex.d/bin

    Default directory to store symbolic links.

    This is not necessary, but it seems a good idea to make special directory to contain symbolic links for optex, placing it in your command search path. Then you can easily add/remove it from the path, or create/remove symbolic links.

ENVIRONMENT

  • OPTEX_ROOT

    Override default root directory ~/.optex.d.

  • OPTEX_CONFIG

    Override default configuration file OPTEX_ROOT/config.toml.

  • OPTEX_MODULE_PATH

    Set module paths separated by colon (:). These are inserted before standard path.

  • OPTEX_BINDIR

    Override default symbolic link directory OPTEX_ROOT/bin.

SEE ALSO

Getopt::EX, Getopt::EX::Loader, Getopt::EX::Module

App::optex::textconv

App::optex::xform

AUTHOR

Kazumasa Utashiro

LICENSE

You can redistribute it and/or modify it under the same terms as Perl itself.

Copyright ©︎ 2017-2024 Kazumasa Utashiro

optex's People

Contributors

kaz-utashiro avatar manwar avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

manwar

optex's Issues

scroll region を切るモジュールを作る

コマンドを実行する時に、コマンドラインが画面から消えて欲しくないことがある。
そういう時のために、画面上の現在のカーソルポジションから下の部分にスクロールリージョンを設定する。
あるいは apt install が行っているように、行数を指定してリージョンを切る。

Multiple module declaration causes unexpected behavior

This works fine.

$ jot 10 | optex -Mdebug column -Mxform --xform-encode ansi -x
optex: load /Users/utashiro/.optex.d/column.rc
@ARGV = -Mxform --xform-encode ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=$<shift> ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub App::optex::xform::encode=mode=ansi
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
@ARGV =  &set(PREFORK=&$<shift>) App::optex::xform::encode=mode=ansi -x
@ARGV =   -x
optex: exec column -x
1	2	3	4	5	6	7	8	9	10

But putting -Mutil::filter option to optex causes error:

$ jot 10 | optex -Mutil::filter -Mdebug column -Mxform --xform-encode ansi -x
optex: load /Users/utashiro/.optex.d/column.rc
@ARGV = -Mxform --xform-encode ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=$<shift> ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub App::optex::xform::encode=mode=ansi
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
optex: exec column --psub App::optex::xform::encode=mode=ansi -x
column: illegal option -- -
usage: column [-tx] [-c columns] [-s sep] [file ...]

Putting same module for subcommand does not effect:

$ jot 10 | optex -Mdebug column -Mutil::filter -Mxform --xform-encode ansi -x
optex: load /Users/utashiro/.optex.d/column.rc
@ARGV = -Mutil::filter -Mxform --xform-encode ansi -x
@ARGV = -Mxform --xform-encode ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=$<shift> ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub App::optex::xform::encode=mode=ansi
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
@ARGV =  -Mutil::filter --psub App::optex::xform::encode=mode=ansi -x
@ARGV = -Mutil::filter --psub
@ARGV =   --psub App::optex::xform::encode=mode=ansi -x
@ARGV =  &set(PREFORK=&$<shift>) App::optex::xform::encode=mode=ansi -x
@ARGV =   -x
optex: exec column -x
1	2	3	4	5	6	7	8	9	10

Test suite fails (with older Getopt::EX::Hashed?)

On some of my smoker systems the test suite fails:

Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.
Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.

#   Failed test at t/01_run.t line 13.
#          got: '2'
#     expected: '0'
Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.
Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.

#   Failed test at t/01_run.t line 18.
#          got: '255'
#     expected: '0'
Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.

#   Failed test at t/01_run.t line 19.
#          got: '255'
#     expected: '0'
Can't load module "util::filter".
Attempt to access disallowed key 'DEFAULT' in a restricted hash at /opt/perl-5.30.2/lib/site_perl/5.30.2/Getopt/EX/Hashed.pm line 215.

#   Failed test at t/01_run.t line 24.
#          got: '25'
#     expected: '0'
# Looks like you failed 4 tests of 9.
t/01_run.t ...... 
Dubious, test returned 4 (wstat 1024, 0x400)
Failed 4/9 subtests 

#   Failed test 'no-module'
#   at t/02_config.t line 50.
#          got: ''
#     expected: '-M
# '

#   Failed test 'alias'
#   at t/02_config.t line 53.
#          got: ''
#     expected: '2
# '

#   Failed test 'alias string'
#   at t/02_config.t line 56.
#          got: ''
#     expected: 'hello  world
# '
# Looks like you failed 3 tests of 6.
t/02_config.t ... 
Dubious, test returned 3 (wstat 768, 0x300)
Failed 3/6 subtests 

Statistical analysis suggests that this happens if an older version of Getopt::EX::Hashed is installed (0.9917 is OK, other versions probably not):

****************************************************************
Regression 'mod:Getopt::EX::Hashed'
****************************************************************
Name                   Theta          StdErr     T-stat
[0='const']           0.0000          0.0000      21.92
[1='eq_0.9917']       1.0000          0.0000    27180413999190232.00

R^2= 1.000, N= 98, K= 2
****************************************************************

Typo in ABSTRACT

The abstract "optex command module direcrtory" should be "optex command module directory"

t/02_config.t fails on most installations

On most of my smokers the test suite fails:

...
#   Failed test 'symlink, no-module'
#   at t/02_config.t line 37.
#          got: ''
#     expected: '-M
# '

#   Failed test 'symlink, alias'
#   at t/02_config.t line 39.
#          got: ''
#     expected: 'yes'
# Looks like you failed 2 tests of 5.
t/02_config.t ... 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/5 subtests 
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.