nakedmudv3.3/
nakedmudv3.3/lib/
nakedmudv3.3/lib/logs/
nakedmudv3.3/lib/misc/
nakedmudv3.3/lib/players/
nakedmudv3.3/lib/txt/
nakedmudv3.3/lib/world/
nakedmudv3.3/lib/world/examples/
nakedmudv3.3/lib/world/examples/mproto/
nakedmudv3.3/lib/world/examples/oproto/
nakedmudv3.3/lib/world/examples/reset/
nakedmudv3.3/lib/world/examples/rproto/
nakedmudv3.3/lib/world/examples/trigger/
nakedmudv3.3/lib/world/limbo/
nakedmudv3.3/lib/world/limbo/room/
nakedmudv3.3/lib/world/limbo/rproto/
nakedmudv3.3/src/alias/
nakedmudv3.3/src/char_vars/
nakedmudv3.3/src/editor/
nakedmudv3.3/src/example_module/
nakedmudv3.3/src/help/
nakedmudv3.3/src/set_val/
nakedmudv3.3/src/socials/
nakedmudv3.3/src/time/
//*****************************************************************************
//
// script_editor.c
//
// this is an extention of the basic script editor (/src/editor/editor.h) to
// be tailored for script editing. Provides syntax coloring and line number
// display, and auto indenting.
//
//*****************************************************************************

#include "../mud.h"
#include "../socket.h"
#include "../auxiliary.h"

#include "../editor/editor.h"
#include "script_editor.h"
#include "scripts.h"



//*****************************************************************************
// auxiliary data and functions
//*****************************************************************************
typedef struct script_editor_aux_data {
  int      indent; // how far are we indented for our next line of code?
  bool autoindent; // do we autoindent after encountering a colon?
} SCRIPT_EDITOR_AUX_DATA;

SCRIPT_EDITOR_AUX_DATA *
newScriptEditorAuxData() {
  SCRIPT_EDITOR_AUX_DATA *data = malloc(sizeof(SCRIPT_EDITOR_AUX_DATA));
  data->autoindent = TRUE;
  data->indent     = 0;
  return data;
}



//*****************************************************************************
// local functions and data structures
//*****************************************************************************
EDITOR *script_editor = NULL;


//
// toggle the socket's autoindent in script editning
void scriptEditorToggleAutoindent(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  SCRIPT_EDITOR_AUX_DATA *data = 
    socketGetAuxiliaryData(sock, "script_editor_aux_data");
  data->autoindent = (data->autoindent + 1) % 2;
  send_to_socket(sock, "Autoindent %s.\r\n", 
		 (data->autoindent ? "enabled" : "supressed"));
}

//
// increase the indentation in our script by 2
void scriptEditorIndent(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
  data->indent += 2;
  send_to_socket(sock, "Editor indented to %d spaces.\r\n", data->indent);
}

//
// decrease the indentation in our script by 2
void scriptEditorUndent(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
  data->indent -= 2;
  if(data->indent < 0)
    data->indent = 0;
  send_to_socket(sock, "Editor undented to %d spaces.\r\n", data->indent);
}

//
// return what our current level of indenting is
int socketGetScriptEditorIndent(SOCKET_DATA *sock) {
  SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
  return data->indent;
}

//
// append new text to the script editor. Make sure we add the appropriate amount
// of spaces before the addition, and increment/decrement our indent as needed
void scriptEditorAppend(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  SCRIPT_EDITOR_AUX_DATA *data = 
    socketGetAuxiliaryData(sock, "script_editor_aux_data");

  // if we're playing with else/elif/case, take down the input a notch
  if(data->autoindent) {
    if(!strncmp(arg, "except:", 7) ||
       !strncmp(arg, "except ", 7) ||
       !strncmp(arg, "else:",   5) ||
       !strncmp(arg, "elif ",   5) ||
       !strncmp(arg, "case ",   5))
      scriptEditorUndent(sock, NULL, NULL);

    // add in our indents if neccessary
    if(data->indent > 0) {
      char fmt[20];
      sprintf(fmt, "%%%ds", data->indent);
      bprintf(buf, fmt, " ");
    }
  }

  // cat the new line of code
  bufferCat(buf, arg);
  bufferCat(buf, "\n");

  // see if we need to change our indent
  if(data->autoindent) {
    int len = strlen(arg);
    if(len > 0 && arg[len-1] == ':')
      scriptEditorIndent(sock, NULL, NULL);
  }
}

//
// list the script buffer to the socket, but do all of our syntax highlighting
void scriptEditorList(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  script_display(sock, bufferString(buf), TRUE);
}

//
// \r really screws up python; this function makes sure they're all stripped out
void scriptEditorFormat(SOCKET_DATA *sock, char *arg, BUFFER *buf) {
  bufferReplace(buf, "\r", "", TRUE);
  text_to_buffer(sock, "Script formatted.\r\n");
}

//
// prepare our socket to use the script editor
void socketInitScriptEditor(SOCKET_DATA *sock) {
  SCRIPT_EDITOR_AUX_DATA *data = socketGetAuxiliaryData(sock, "script_editor_aux_data");
  data->indent = 0;
}

//
// bufferInsert appends a carriage return to the end of the argument, but this
// makes Python choke. Soooo... we have to do the append, and then remove the
// carriage return that was inserted.
void scriptEditorInsert(SOCKET_DATA *sock, char *arg, BUFFER *buf) { 
  char tmp[SMALL_BUFFER];
  arg = one_arg(arg, tmp);
  int line = atoi(tmp);
  if(!isdigit(*tmp) || !bufferInsert(buf, arg, line))
    text_to_buffer(sock, "Insertion failed.\r\n");
  else {
    text_to_buffer(sock, "Line inserted.\r\n");
    bufferReplace(buf, "\r", "", TRUE);    
  }
}


//*****************************************************************************
// implementation of script_editor.h
//*****************************************************************************
void init_script_editor() {
  script_editor = newEditor();
  editorSetAppend(script_editor, scriptEditorAppend);
  editorSetInit(script_editor, socketInitScriptEditor);
  editorAddCommand(script_editor, "v", "        Indent down the script editor",
		   scriptEditorUndent);
  editorAddCommand(script_editor, "^", "        Indent up the script editor",
		   scriptEditorIndent);
  editorAddCommand(script_editor, "-", "        Toggle auto-indenting",
		   scriptEditorToggleAutoindent);
  editorAddCommand(script_editor, "l", "        List the current buffer contents",
		   scriptEditorList);
  editorAddCommand(script_editor, "f", "        Strips all bad characters out of the script",
		   scriptEditorFormat);
  editorAddCommand(script_editor, "i", "# <txt> Insert new text at the specified line number",
		   scriptEditorInsert);

  auxiliariesInstall("script_editor_aux_data", 
		     newAuxiliaryFuncs(AUXILIARY_TYPE_SOCKET,
				       newScriptEditorAuxData, free,
				       NULL, NULL, NULL, NULL));
}