# pyfuns.py         -*- coding: iso-8859-1 -*-
# Copyright (c) 2005 Günter Milde
# Released under the terms of the GNU General Public License (ver. 2 or later)
"""Convenience and extension functions for LyX using the lyx.py module
   for communication with the lyxserver
   
   Adds a (crude) word-count and an external edit feature to your LyX
   The word count needs the `xclip` command line tool
   TODO: use tkinter (or another python GUI interface)
   
   Only tested on Linux
"""
import os, commands, re
from LyX.lyxclient import LyXError
from LyX import lfuns, bindings


# Functions for the LyXClient
# ---------------------------

def kbd_quit():
    """Stop the listening loop"""
    lfuns.message("keyboard interupt")
    raise LyXError, "keyboard interupt"


def apropos(pattern):
    """Show lfuns matching regexp pattern in help buffer"""
    matches = bindings.apropos(pattern)
    try:
        lfuns.server_get_layout()
    except:
        lfuns.buffer_new()
    lfuns.escape()
    lfuns.note_insert()
    lfuns.self_insert("Apropos: " + pattern)
    lfuns.break_paragraph()
    for match in matches:
        lfuns.break_line()
        lfuns.self_insert(match)
    return matches

# print "".join(apropos("new"))

def where_is(fun):
    """Show keybinding(s) for lfun (matching regexp) in status line"""
    keys = bindings.where_is(fun).keys()
    lfuns.message(", ".join(keys))
    return keys

# print where_is("buffer-new")

def showkey(key):
    """Show lfun for key in status line"""
    result = bindings.showkey(key)
    lfuns.message(result)
    return result

# print showkey("M-x")

def buffer_select():
    """Mark (select) the whole current buffer"""
    lfuns.buffer_begin()
    lfuns.buffer_end_select()

def line_select():
    """Mark (select) the current line"""
    lfuns.line_begin()
    lfuns.line_end_select()

def get_x_selection():
    """Return the current X selection using the `xclip` command line tool
    
    TODO use selection_get from tkinter
    """
    return commands.getoutput("xclip -o")

def get_lyx_selection():
    """Return the lyx selection
    
    Copy the current selection (thus propagating it to the X selection) and
    fetch it using the `xclip` command line tool.
    
    Might be replaced by e.g. selection_get from tkinter or an internal lfun
    """
    lfuns.copy()
    return get_x_selection()

def get_buffer():
    """Select whole buffer and get the selection"""
    lfuns.bookmark_save(3)
    buffer_select()
    selection = get_lyx_selection()
    lfuns.bookmark_goto(3)
    return selection

# Word count
def count_words():
    """Export buffer to the X selection and count there
    """
    text = get_buffer()
    count = len(text.split())
    lfuns.message("count_words: %d Words"%count)
    return count

# External editing of the source file
def external_edit(editor=os.getenv("EDITOR")):
    """External edition of the source file
    
       editor -- shell command for editing the source file
       
                 Defaults to the EDITOR environment variable
                 
                 By providing a (e.g. sed) command, you can do all sorts of
                 magic to the lyx file 'on the fly'
    """
    if not editor:
        # TODO: ask for editing cmd in the minibuffer
        raise LyXError, "give an editing command or set the EDITOR environment variable"
    # Preparation
    fname = lfuns.server_get_name()  # get the current file's name
    lfuns.buffer_write()               # save
    # Call the editor
    os.system(editor + " " + fname)
    # Relaod the file (do not use "reload", as this is in reality a "restore")
    lfuns.file_open(fname)

