4coder/4coder_default_building.cpp

193 lines
7.2 KiB
C++

#include "4coder_custom.h"
#define FCPP_STRING_IMPLEMENTATION
#include "4coder_string.h"
#include "4coder_helper.h"
CUSTOM_COMMAND_SIG(build_search){
// NOTE(allen|a3.3): An example of traversing the filesystem through parent
// directories looking for a file, in this case a batch file to execute.
//
//
// Step 1: Grab all of the user memory (or, you know, less if you've got better
// thing to do with some of it). Make a string and store the hot directory in it.
//
// Step 2: app->file_exists queries the file system to see if "<somedir>/build.bat" exists.
// If it does exist several parameters are pushed and cmdid_command_line is executed:
// - par_flags: flags for specifiying behaviors
// CLI_OverlapWithConflict - (on by default) if another CLI is still using the output buffer
// that process is detached from the buffer and this process executes outputing to the buffer
// CLI_AlwaysBindToView - if set, the current view always switches to the output buffer
// even if the output buffer is open in another view
//
// - par_name: the name of the buffer to fill with the output from the process
// - par_buffer_id: the buffer_id of the buffer to to fill with output
// If both are set buffer_id is used and the name is ignored.
// If neither is set the command runs without storing output anywhere.
//
// - par_cli_path: sets the path from which the command is executed
// If this parameter is unset the command runs from the hot directory.
//
// - par_cli_command: sets the actual command to be executed, this can be almost any
// command that you could execute through a command line interface.
// If this parameter is unset the command get's it's command from the range between
// the mark and cursor.
//
// Step 3: If the batch file did not exist change the dir string to the parent directory using
// app->directory_cd. The cd function can also be used to navigate to subdirectories.
// It returns true if it can actually move in the specified direction, and false otherwise.
//
// This doesn't actually change the hot directory of 4coder, it's only effect is to
// modify the string you passed in to reflect the change in directory if that change was possible.
int old_size;
int size = app->memory_size/2;
unsigned int access = AccessAll;
View_Summary view = app->get_active_view(app, access);
String dir = make_string(app->memory, 0, size);
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
String command = make_string((char*)app->memory + size, 0, size);
for(;;){
old_size = dir.size;
append(&dir, "build.bat");
if (app->file_exists(app, dir.str, dir.size)){
dir.size = old_size;
append(&command, '"');
append(&command, dir);
append(&command, "build\"");
app->exec_system_command(app, &view,
buffer_identifier(literal("*compilation*")),
dir.str, dir.size,
command.str, command.size,
CLI_OverlapWithConflict);
break;
}
dir.size = old_size;
if (app->directory_cd(app, dir.str, &dir.size, dir.memory_size, literal("..")) == 0){
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
command = make_lit_string("echo couldn't find build.bat");
app->exec_system_command(app, &view,
buffer_identifier(literal("*compilation*")),
dir.str, dir.size,
command.str, command.size,
CLI_OverlapWithConflict);
break;
}
}
}
CUSTOM_COMMAND_SIG(build_in_build_panel){
Buffer_Summary buffer = app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
View_Summary build_view = {0};
View_Summary original_view = app->get_active_view(app, AccessAll);
if (buffer.exists){
build_view = get_first_view_with_buffer(app, buffer.buffer_id);
}
if (!build_view.exists){
exec_command(app, cmdid_open_panel_hsplit);
build_view = app->get_active_view(app, AccessAll);
}
app->set_active_view(app, &build_view);
exec_command(app, build_search);
app->set_active_view(app, &original_view);
}
CUSTOM_COMMAND_SIG(close_build_panel){
Buffer_Summary buffer = app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
if (buffer.exists){
View_Summary build_view = get_first_view_with_buffer(app, buffer.buffer_id);
View_Summary original_view = app->get_active_view(app, AccessAll);
app->set_active_view(app, &build_view);
exec_command(app, cmdid_close_panel);
app->set_active_view(app, &original_view);
}
}
CUSTOM_COMMAND_SIG(change_active_panel_skip_build){
Buffer_Summary buffer = app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
if (buffer.exists){
View_Summary build_view = get_first_view_with_buffer(app, buffer.buffer_id);
View_Summary view = app->get_active_view(app, AccessAll);
int prev_view_id = view.view_id;
exec_command(app, cmdid_change_active_panel);
view = app->get_active_view(app, AccessAll);
for (;(view.view_id != prev_view_id &&
build_view.view_id == view.view_id);){
prev_view_id = view.view_id;
exec_command(app, cmdid_change_active_panel);
view = app->get_active_view(app, AccessAll);
}
}
}
CUSTOM_COMMAND_SIG(open_file_in_quotes_build){
char file_name_[256];
String file_name = make_fixed_width_string(file_name_);
if (file_name_in_quotes(app, &file_name)){
exec_command(app, change_active_panel_skip_build);
View_Summary view = app->get_active_view(app, AccessAll);
view_open_file(app, &view, expand_str(file_name), false);
}
}
// TODO(allen): This is a bit nasty. I want a system for picking
// the most advanced and correct version of a command to bind to a
// name based on which files are included.
#ifndef OPEN_FILE_IN_QUOTES
# define OPEN_FILE_IN_QUOTES 2
#elif OPEN_FILE_IN_QUOTES <= 2
# undef OPEN_FILE_IN_QUOTES
# define OPEN_FILE_IN_QUOTES 2
#endif
#if OPEN_FILE_IN_QUOTES <= 2
# ifdef open_file_in_quotes
# undef open_file_in_quotes
# endif
# define open_file_in_quotes open_file_in_quotes_build
#endif
CUSTOM_COMMAND_SIG(open_in_other_build){
exec_command(app, change_active_panel_skip_build);
exec_command(app, cmdid_interactive_open);
}
// TODO(allen): This is a bit nasty. I want a system for picking
// the most advanced and correct version of a command to bind to a
// name based on which files are included.
#ifndef OPEN_IN_OTHER
# define OPEN_IN_OTHER 1
#elif OPEN_IN_OTHER <= 1
# undef OPEN_IN_OTHER
# define OPEN_IN_OTHER 1
#endif
#if OPEN_IN_OTHER <= 1
# ifdef open_in_other
# undef open_in_other
# endif
# define open_in_other open_in_other_build
#endif