DISCLAIMER. English language used here only for compatibility (ASCII only), so any suggestions about my bad grammar (and not only it) will be greatly appreciated.

четверг, 20 мая 2010 г.

[summary][draft][part] Tabs in vim

DISCLAIMER. English language used here only for compatibility (ASCII only), so any suggestions about my bad grammar (and not only it) will be greatly appreciated.

Status: summary.
State: draft,part.
Detailed description: Some tables for illustrate <Tab>'s handling in vim. See vim help for details.

Tabs in vim {{{

    'sts' and 'sta' options {{{

        Following options affect <Tab>s and indents:

            'tabstop'       'ts'
            'shiftwidth'    'sw'
            'softtabstop'   'sts'
            'smarttab'      'sta'
            'expandtab'     'et'

        'sw' and 'ts' define standard vim operations behavior, they are not
        switches for some features (hence they're always set and always used).
        But 'sts' and 'sta' enables additional features, which affect (change)
        some vim operations behavior (hence, they can be unset to turn feature
        off).

        Table below shows what option will be used to determine how many
        positions insert or delete during some editing operations depending on
        activated modes: both 'sts' and 'sta' are off (default), 'sts' set,
        'sta' set and both 'sts' and 'sta' set. When editing operation insert
        less (or more) positions, than real <Tab> counts for, mix from spaces
        and real <Tab>s are used.


    +--------------------------+-------------------------------------------+
    |    Operation             |   Will be inserted .. positions           |
    |                          +------+-----------+-----------+------------+
    |                          |      | +sts      | +sta      | +sts +sta  |
    +--------------------------+------+-----------+-----------+------------+
    | Use >> , etc             |  sw  | sw        |  sw       |  sw        |
    +--------------------------+------+-----------+-----------+------------+
    | Type <Tab> or <BS>       |  ts  | sts (mix) |           |            |
    |                          +      +           +-----------+------------+
    |     at the start of line |      |           |  sw (mix) |  sw (mix)  |
    |                          +      +           +-----------+------------+
    |     in other places      |      |           |  ts       |  sts (mix) |
    +--------------------------+------+-----------+-----------+------------+
    | Real <Tab> length        |  ts  | ts        |  ts       |  ts        |
    +--------------------------+------+-----------+-----------+------------+

    }}}
    ':retab' and changing 'ts' option value {{{

        'ts' option changes real tabstop, but does not change text. Hence,
        indents, which made according to old tabstop, probably will be messed
        (i.e there will be visible changes in text), but actual file remains
        untouched. So, using 'undo' after changing 'ts' has no sense.

        :retab command changes both 'ts' option and text according to new 'ts'
        value in such way, that all indents remain the same (there will be no
        visible changes), though actual file will be changed (to preserve
        visible indents :retab pads them, if necessary, with spaces). So,
        using 'undo' after :retab recover text to previous state, but not
        recover 'ts' to previous value, hence indents may be messed (like
        after you change only 'ts') and to recover visible text state you need
        set 'ts' to previous value. Table below summarizes that.


        +-------------------+---------------+-----------+
        |                   | Change 'ts'   | :retab    |
        +-------------------+---------------+-----------+
        | 'ts' changed?     | yes           | yes       |
        +-------------------+---------------+-----------+
        | File changed?     | no            | yes       |
        +-------------------+---------------+-----------+
        | Visible changes?  | yes           | no        |
        +-------------------+---------------+-----------+

    }}}

}}}


вторник, 4 мая 2010 г.

[method][draft][part][need_check] (bash) passing arguments to function

DISCLAIMER. English language used here only for compatibility (ASCII only), so any suggestions about my bad grammar (and not only it) will be greatly appreciated.

Status: method.
State: suggestion,draft,part,need_check.
Detailed description: One more method for passing arguments to bash function.

Outline: below under 'passing argument as pointer' i mean passing argument by name:
function f() {
}

declare var='abc'
f var  # not f "$var"
This may be considered as analogy for pointers (in C), i think :-)

1. Passing argument as pointer to function sometimes may require redefinition
   it as local variable in order to preserve referred data. Though, generally
   pointer used to provide to function ability to modify caller's environment,
   in bash it may be used, to skip unnecessary copying of big argument, if we
   want to redefine all positional parameters to local variables (names
   1, 2, 3,.. is bad whenever, and also positional parameters may be used for
   some tricks, so it's better, when they do not contain useful data).

        eval "
                $(declare -p $2 | sed -e's/^[^=]\+=/local -a shortopts=/' );
                $(declare -p $3 | sed -e's/^[^=]\+=/local -a longopts=/');
        "

   Above construction is, seemingly, the only way. To correctly redefine
   pointer to local variable we should honour several contraints:
        1. we should not define any local variable before all pointers will be
           expanded, because otherwise there is a chance, that defined local
           variable name is match with some pointed to variable's name and we
           lose access to it.
        2. we should preserve all special characters inside pointed data.

   To handle first constraint, we need `eval`.

   To handle second, we should properly quote expanded pointed to variable's
   value:

        ${[@]} - split elements correctly only during first expand, but in the
        second (done in `eval`) these boundaries will be lost and bash splits
        elements by 'metacharacters', not by IFS or anything else (info bash,
        ch-2).
        ${[*]} - my be used, perhaps, with IFS=',', and then.. something
        artificial to set up quoting by brace expansion. But this rarely works,
        though (i don't know working example).
        `declare` - seems, only way to obtain correct quoting without many
        evals and artificial tricks. But its output, perhaps, should be
        processed by some program to replace variable name to desired one.


[summary][draft][part] Bash script parsing

DISCLAIMER. English language used here only for compatibility (ASCII only), so any suggestions about my bad grammar (and not only it) will be greatly appreciated.

Status: summary.
State: draft,part.
Detailed description: illustration for info bash ch-2.

Bash script parsing units:

                    token = single unit
                   /     \
                 /         \
               /             \
             /                 \
          word                operator
         / | \                /     \
       /   |   \             /       \
     /     |     \          /         \
reserved  name    ..     control     redirection
word                     operator     operator


              metacharacter - separate words (or tokens?)
              /     \   
            /         \ 
          /             \
       blank           some (why not all?)
                       control operators