# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/04_exhash.ipynb.

# %% auto #0
__all__ = ['msg_lnhashview', 'msg_exhash', 'file_lnhashview', 'file_exhash']

# %% ../nbs/04_exhash.ipynb #d6291515
from .core import *
from exhash import *

# %% ../nbs/04_exhash.ipynb #c7a53c95
async def msg_lnhashview(id:str):
    "Show lnhash-addressed lines of a message"
    msg = await read_msgid(id=id)
    return '\n'.join(lnhashview(msg['content']))

# %% ../nbs/04_exhash.ipynb #9bdae034
async def msg_exhash(id:str, cmds:list):
    """Verified line-addressed editor. Apply commands to msg `id` contents, return lnhashview(result).
    **NB**: *all* exhash commands *must* start with an address.
    The *only* allowed addresses are a single lnhash, or a pair separated by `,`. (I.e no `%`, `.`, etc.)
    **NB**: hashes are checked only *once* before all commands are run. So passing multiple commands work fine, even if hashes change.

    Commands are like `ex`, but use lnhash addresses instead of bare line numbers: ``lineno|hash|cmd`` where hash is a 4-char hex content hash.
    Use `msg_lnhashview(text)` to get addresses before first use.

    Addressing:
      Single:   ``12|a3f2|cmd``
      Range:    ``12|a3f2|,15|b1c3|cmd``
      Special:  ``0|0000|`` targets before line 1 (only with a or i)

    Commands:
      s/pat/rep/[flags]  Substitute (regex). Flags: g=all, i=case-insensitive
      d                  Delete line(s)
      a                  Append text after line
      i                  Insert text before line
      c                  Change/replace line(s)
      j                  Join with next line; with range, joins all
      m dest             Move line(s) after dest address
      t dest             Copy line(s) after dest address
      >[n]               Indent n levels (default 1, 4 spaces each)
      <[n]               Dedent n levels (default 1)
      sort               Sort lines alphabetically
      p                  Print (include in output without changing)
      g/pat/cmd          Global: run cmd on matching lines
      g!/pat/cmd         Inverted global (also v/pat/cmd)

    `cmds` is a required list of command strings. For `a`/`i`/`c`, include the text block in the same command string after a newline."""
    msg = await read_msgid(id=id)
    txt = msg['content']
    res = exhash(txt, cmds)
    res = '\n'.join(res['lines'])
    upres = await update_msg(id=id, content=res)
    assert upres.startswith('_'), f"Message update failed: {upres}"
    return '\n'.join(lnhashview(res))

# %% ../nbs/04_exhash.ipynb #b57b7099
def file_lnhashview(path:str):
    "Show lnhash-addressed lines of a file"
    return '\n'.join(lnhashview(Path(path).read_text()))

# %% ../nbs/04_exhash.ipynb #0647eeb2
def file_exhash(path:str, cmds:list[str]):
    """Verified line-addressed editor for files. Apply commands to file at `path`, return lnhashview(result).
    See `doc(msg_lnhashview)` for details"""
    txt = Path(path).read_text()
    res = '\n'.join(exhash(txt, cmds)['lines'])
    Path(path).write_text(res)
    return '\n'.join(lnhashview(res))
