q3cpma

Difference between version 25 and 31 - Previous - Next
===
set website    https://git.sr.ht/~q3cpma/
set location   France
set email      [email protected]
===

----

My miscellaneous Tcl utilities are https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl%|%here%|% and they contain:    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#L148205%|%destructuring_bind%|%: like the CL one, enabling a defmacro-like defun
======
% util::defun f {&whole w req &key k1 {k2 X} {k3 Y k3_supplied}} {
      foreach arg {w req k1 k2 k3 k3_supplied} {
          puts "$arg: [list [set $arg]]"
      }
  }
% f 1
w: 1
req: 1
k1: {}
k2: X
k3: Y
k3_supplied: 0
% f 1 :k3 Y :k2 2 :k1 3
w: {1 :k3 Y :k2 2 :k1 3}
req: 1
k1: 3
k2: 2
k3: Y
k3_supplied: 1
======    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#228L417%|%atexit%|%: schedule script executions at exit
======
% util::atexit add {puts "hello world"}
% util::atexit add {puts [clock format [clock seconds]]}
% util::atexit add {global env; puts "env: $env(HOME)"}
% util::atexit del {puts "hello world"}
% exit
Wed Jul 14 14:27:58 CEST 2021
env: /home/user
======    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#3L1675%|%quasiquote%|%: yet another way to selectively expand variables
======
% set var1 hello
% set {var 2} world
% set var3 {1 2}
% eval [util::quasiquote var4 foobar var5 {[* 5 5]} var6 {[list 6 6]} {
      puts "`,var1` `,{var 2}` `,var3` `\[+ ,@var3\] = [+ ,@var3]` `,var4` `,@var5` `,@var6`"
% }]
`hello` `world` `{1 2}` `[+ 1 2] = 3` `foobar` `25` `6 6`
======    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#40L700%|%format_paragraph%|%: like `textutil::adjust` followed by `textutil::indent` with terminal markup
<<inlinehtml>>
<div class='sh_sourceCode'><button class='copybtn btn pull-right' data-clipboard-target='#mkup_code_perso1' title='Click to copy code snippet to clipboard'><span class='glyphicon glyphicon-copy' aria-hidden='true'></span></button><pre id='mkup_code_perso1' class='sh_tcl sh_sourceCode'>
% puts [util::format_paragraph {**Lorem __ipsum__ dolor** sit --amet--, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum} indent 4 width 70]</pre>
<pre>    <b>Lorem <u>ipsum</u> dolor</b> sit <s>amet</s>, consectetur adipiscing elit, sed do
    eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
    ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum
</pre></div>
<<inlinehtml>>    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#514L809%|%autocli%|%: all-in-one CLI creation handling option parsing and help text creation

<<inlinehtml>>
<div class='sh_sourceCode'><button class='copybtn btn pull-right' data-clipboard-target='#mkup_code_perso2' title='Click to copy code snippet to clipboard'><span class='glyphicon glyphicon-copy' aria-hidden='true'></span></button><pre id='mkup_code_perso2' class='sh_tcl sh_sourceCode'>
% set argv {-opt1 -opt2 foobar myarg}
% set argc 4
% set opts [util::autocli \
    {opt1 {flag "Opt1 description"} opt2 {param default PARAM_NAME "Opt2 description"}} \
    "Program name" \
    "Short description" \
    {{SYNOPSIS1_ARG1 [SYNOPSIS1_ARG2...]} {SYNOPSIS2_ARG1 SYNOPSIS2_ARG2}} \
    {"Long description as a list of indented and formatted paragraphs"
    "    with some **markup**"}]
opt1 1 opt2 foobar
% set argv
foobar
% util::usage stdout</pre>
<pre><b>NAME</b>
    Program name - Short description

<b>SYNOPSIS</b>
    <b>Program name</b> <b>[</b><u>OPTION</u><b>]</b>... <u>SYNOPSIS1_ARG1</u> <b>[</b><u>SYNOPSIS1_ARG2</u>...<b>]</b>
    <b>Program name</b> <b>[</b><u>OPTION</u><b>]</b>... <u>SYNOPSIS2_ARG1</u> <u>SYNOPSIS2_ARG2</u>

<b>DESCRIPTION</b>
    Long description as a list of indented and formatted paragraphs
          with some <b>markup</b>

<b>OPTIONS</b>
    <b>-opt1</b>
        Opt1 description

    <b>-opt2</b> <u>PARAM_NAME</u>
        Opt2 description
        Defaults to "default".

    <b>-help</b>
        Print this help message and exit.

</pre></div>
<<inlinehtml>>    * https://git.sr.ht/~q3cpma/tcl-misc/tree/master/item/util.tcl#L96661%|%parse%|%: yet another AWK emulation proc, with some niceties here and there (srange to adress line fragments by field number, exit to control the flow with granularity)
======
# List all mountable hotplugged disks/partitions
% exec lsblk -nproNAME,TYPE,HOTPLUG,FSTYPE,MOUNTPOINT | awk {$2 ~ /^(part|disk)$/ && $3 == 1 && NF == 4 {print $1}}
/dev/sdd1
/dev/sde
/dev/sde2
/dev/sde1
% util::parse [exec lsblk -nproNAME,TYPE,HOTPLUG,FSTYPE,MOUNTPOINT] {        {[~ {^(part|disk)$} $21] && $32 == 1 && $NF == 4} {
                lappend RETret $10
        }        END {return $ret}
}
/dev/sdd1 /dev/sde /dev/sde2 /dev/sde1
======
along with a lot of small stuff:
  * misc: variables (variable with multiple nameus), ? (ternary), shift (ulike sh), ipc_fifo, pretty_list (for use in a sentence), every (works with namespaces)
  * filesystem:f is_dir_empty, glob_mtime (glob sorted by mtime)
  * functional: lambda, Lispapply, gensym, lfilter, lreduceff, lreduceip
  * dict: get? (exist + get in one go), assign (assign the dict content to local variables), join, various nested dict additions, etc...).

----

Some Tcl based projects:    * https://sr.ht/~q3cpma/mangadex-tools/%|%mangadex-tools%|%
    * https://sr.ht/~q3cpma/haggle/%|%haggle%|%
    * https://git.sr.ht/~q3cpma/lemonbar-tcl%|%lemonbar-tcl%|%

Other stuff in separate Wiki pages:    * [Atom feeds]

----

Some "problems" I identified during my Tcl journey:    * Need for a more pinpoint subst, like Lisp quasi-quoting; needed for Tcl style "closures" (cf aforementioned quasiquote).
    * Named parameters (options, in the case of Tcl), my defun is too slow.
    * Fossil instead Git... let's face it, Git won the VCS war a long time ago, and Fossil more than probably detracts a significative population from contributing (probably even more than something like CVS or subversion).
    * Not something I expect to be solved (it's a lot of work, after all), but I've really been spoilt by LSP/SLIME and its lack in Tcl is now jarring to me.
    * event loop: a way to set an after timer instead of cancelling then adding it anew.
    * exec: still not fixed (TIP 424 and 259).
    * trace: add a way to trace all/any variables (including variable creation) and access to unknown variables, provide the previous value during a write, integrate with dicts and lists (dict trace/ltrace?).
    * socket: lacks a well supported UD sockets library, portable way of specifying timeout?
    * string: add a -dict option to compare (https://core.tcl-lang.org/tcl/tktview?name=667ec8ff04%|%ticket%|%).
    * binary scan: no way to get the cursor position (https://core.tcl-lang.org/tcl/tktview?name=3551813%|%ticket%|%), would like a more FP -inline switch.
    * binary format: option to switch zero padding position to end instead of beginning.
    * namespace ensemble: add extend subcommand.
    * gets: no getdelim equivalent (chan configure -eol?).
    * coroutine: not first class, could be done if apply took an offset (in char or bytecode ops?) and a wrapper to track said offset (the local environment can be tracked through the apply bindings).
    * TclOO: use the GC to handle obj lifetime, currently have to use defer most of the time.
Note: mostly inactive as a serious Tcl programmer since I became infatuated with CL; still using it as a scripting language for its superior string handling, nice dictionary API or event loop.

<<categories>> Person