Compare commits

..

No commits in common. "master" and "fix_project_gen" have entirely different histories.

46 changed files with 1347 additions and 3465 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
build/
current_dist*/
distributions/
build_stable/

BIN
4ed.rdbg

Binary file not shown.

26
TODO.md
View File

@ -1,26 +0,0 @@
# TODO
PRIME DIRECTIVE: SIMPLIFY
## Necessary
[] figure out why the built version has a different font size than this one.
## Nice to Have
[] 4coder projects should have a startup script - so you can do things like add cl to the path
[] Look into removing *keyboard* buffer - seems like over long sessions, that could get out of hand
- good first step: print out the memory footprint of this buffer when we exit 4coder, just so we can see what it's taking up
[] multi cursor editing
[] yeet sheet
## Investigations
[] What are fade ranges? Do we need them?
# DONE
[x] matching curly brace highlight
[x] when buffers have the same filename, a short name is appended. I'd prefer to append the path relative to the project, and if the file is outside the project, append the full path.
[x] reload dirty files if there are no local edits to them automatically
[x] remove audio (search @Remove)
[x] backspace through entire filename in navigation strip at top
[x] fix project creation - this should just work out of the box
[x] remove automatic code layout for now

View File

@ -19,11 +19,13 @@ string_from_file_name(Editing_File_Name *name){
internal void
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i64 pos){
edit_pos->cursor_pos = pos;
edit_pos->last_set_type = EditPos_CursorSet;
}
internal void
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, Buffer_Scroll scroll){
edit_pos->scroll = scroll;
edit_pos->last_set_type = EditPos_ScrollSet;
}
internal void

View File

@ -12,7 +12,14 @@
#if !defined(FRED_FILE_H)
#define FRED_FILE_H
typedef i32 Edit_Pos_Set_Type;
enum{
EditPos_None,
EditPos_CursorSet,
EditPos_ScrollSet
};
struct File_Edit_Positions{
Edit_Pos_Set_Type last_set_type;
Buffer_Scroll scroll;
i64 cursor_pos;
};

View File

@ -450,6 +450,7 @@ view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, pos);
view->preferred_x = p.x;
file_edit_positions_set_scroll(&edit_pos, scroll);
edit_pos.last_set_type = EditPos_None;
view_set_edit_pos(view, edit_pos);
}

View File

@ -395,7 +395,7 @@ buffer_bind_name(Thread_Context *tctx, Models *models, Arena *scratch, Working_S
node != used_nodes;
node = node->next){
Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node);
if (file_ptr != 0 && string_match(base_name, string_from_file_name(&file_ptr->unique_name))){
if (file_ptr != 0 && string_match(base_name, string_from_file_name(&file_ptr->base_name))){
Node_Ptr *new_node = push_array(scratch, Node_Ptr, 1);
sll_queue_push(conflict_first, conflict_last, new_node);
new_node->file_ptr = file_ptr;

View File

@ -1,31 +0,0 @@
#!/bin/bash
# If any command errors, stop the script
set -e
# Set up directories
# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux
ME="$(realpath "$0")"
LOCATION="$(dirname "$ME")"
SRC_ROOT="$(dirname "$LOCATION")"
PROJECT_ROOT="$(dirname "$SRC_ROOT")"
if [ ! -d "$PROJECT_ROOT/build" ]; then
mkdir "$PROJECT_ROOT/build"
fi
BUILD_ROOT="$PROJECT_ROOT/build"
BIN_ROOT="$SRC_ROOT/bin"
CUSTOM_ROOT="$SRC_ROOT/custom"
CUSTOM_BIN="$CUSTOM_ROOT/bin"
BUILD_MODE="-DOPT_BUILD"
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"
FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE"
INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT"
# Execute
clang++ $WARNINGS $FLAGS $INCLUDES "$BIN_ROOT/4ed_build.cpp" -g -o "$BUILD_ROOT/build"
pushd "$SRC_ROOT"
"$BUILD_ROOT/build"
popd

View File

@ -17,7 +17,11 @@ BIN_ROOT="$SRC_ROOT/bin"
CUSTOM_ROOT="$SRC_ROOT/custom"
CUSTOM_BIN="$CUSTOM_ROOT/bin"
BUILD_MODE="-DDEV_BUILD"
# Get the build mode
BUILD_MODE="$1"
if [ -z "$BUILD_MODE" ]; then
BUILD_MODE="-DDEV_BUILD"
fi
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"

View File

@ -1,11 +1,10 @@
@echo off
set location=%cd%
set me=%~dp0
set me="%~dp0"
:: REM 4cc\code\bin
REM 4cc\code\bin
cd %me%
REM ..\code\bin
REM 4cc
cd ..\..
@ -35,7 +34,6 @@ if %ERRORLEVEL% neq 0 (set FirstError=1)
if %ERRORLEVEL% neq 0 (goto END)
popd
cd %me%\..
%build_root%\build
:END
if %ERRORLEVEL% neq 0 (set FirstError=1)

View File

@ -1,6 +1,4 @@
#!/bin/bash
pushd $(dirname "${BASH_SOURCE[0]}")/.. > /dev/null > /dev/null
chmod +x bin/build-mac.sh
bin/build-mac.sh "-DPACKAGE_SUPER_X64"
popd > /dev/null

View File

@ -1,4 +1,3 @@
@echo off
SET mypath=%~dp0
call %mypath:~0,-1%\build.bat /DPACKAGE_SUPER_X64
call bin\build.bat /DPACKAGE_SUPER_X64

View File

@ -0,0 +1,276 @@
////////////////////////////////
// NOTE(allen): Default Mixer Helpers
// TODO(allen): intrinsics wrappers
#if OS_LINUX
#include <immintrin.h>
#define _InterlockedExchangeAdd __sync_fetch_and_add
#elif OS_MAC
#include <immintrin.h>
#define _InterlockedExchangeAdd __sync_fetch_and_add
#else
#include <intrin.h>
#endif
function u32
AtomicAddU32AndReturnOriginal(u32 volatile *Value, u32 Addend)
{
// NOTE(casey): Returns the original value _prior_ to adding
u32 Result = _InterlockedExchangeAdd((long volatile*)Value, (long)Addend);
return(Result);
}
function void
def_audio_begin_ticket_mutex(Audio_System *Crunky)
{
u32 Ticket = AtomicAddU32AndReturnOriginal(&Crunky->ticket, 1);
while(Ticket != Crunky->serving) {_mm_pause();}
}
function void
def_audio_end_ticket_mutex(Audio_System *Crunky)
{
AtomicAddU32AndReturnOriginal(&Crunky->serving, 1);
}
////////////////////////////////
// NOTE(allen): Default Mixer
global Audio_System def_audio_system = {};
function void
def_audio_init(void){
block_zero_struct(&def_audio_system);
system_set_source_mixer(&def_audio_system, def_audio_mix_sources);
system_set_destination_mixer(def_audio_mix_destination);
}
function void
def_audio_play_clip(Audio_Clip clip, Audio_Control *control){
clip.control = control;
Audio_System *Crunky = &def_audio_system;
def_audio_begin_ticket_mutex(Crunky);
if (Crunky->pending_clip_count < ArrayCount(Crunky->pending_clips))
{
Crunky->pending_clips[Crunky->pending_clip_count++] = clip;
}
def_audio_end_ticket_mutex(Crunky);
}
internal b32
def_audio_is_playing(Audio_Control *control){
Audio_System *Crunky = &def_audio_system;
b32 result = (Crunky->generation - control->generation < 2);
return(result);
}
internal void
def_audio_stop(Audio_Control *control){
Audio_System *Crunky = &def_audio_system;
def_audio_begin_ticket_mutex(Crunky);
Audio_Clip *clip = Crunky->playing_clips;
for(u32 i = 0;
i < ArrayCount(Crunky->playing_clips);
i += 1, clip += 1){
if (clip->control == control){
clip->at_sample_index = clip->sample_count;
clip->control = 0;
}
}
control->loop = false;
def_audio_end_ticket_mutex(Crunky);
}
function void
def_audio_mix_sources(void *ctx, f32 *mix_buffer, u32 sample_count){
Audio_System *Crunky = (Audio_System*)ctx;
def_audio_begin_ticket_mutex(Crunky);
// NOTE(casey): Move pending sounds into the playing list
{
Crunky->generation += 1;
u32 PendIndex = 0;
Audio_Clip *clip = Crunky->playing_clips;
for(u32 DestIndex = 0;
(DestIndex < ArrayCount(Crunky->playing_clips)) && (PendIndex < Crunky->pending_clip_count);
DestIndex += 1, clip += 1)
{
if (clip->at_sample_index == clip->sample_count)
{
Audio_Control *control = clip->control;
if (control == 0 || !control->loop){
*clip = Crunky->pending_clips[PendIndex++];
}
}
}
Crunky->pending_clip_count = 0;
}
def_audio_end_ticket_mutex(Crunky);
// NOTE(casey): Mix all sounds into the output buffer
{
Audio_Clip *clip = Crunky->playing_clips;
for(u32 SoundIndex = 0;
SoundIndex < ArrayCount(Crunky->playing_clips);
SoundIndex += 1, clip += 1)
{
// NOTE(allen): Determine starting point
Audio_Control *control = clip->control;
if (control != 0 && control->loop && clip->at_sample_index == clip->sample_count){
clip->at_sample_index = 0;
}
u32 base_sample_index = clip->at_sample_index;
// NOTE(casey): Determine how many samples are left to play in this
// sound (possible none)
u32 SamplesToMix = clamp_top((clip->sample_count - clip->at_sample_index), sample_count);
clip->at_sample_index += SamplesToMix;
// NOTE(casey): Load the volume out of the control if there is one,
// and if there is, update the generation and sample index so
// external controllers can take action
f32 LeftVol = clip->channel_volume[0];
f32 RightVol = clip->channel_volume[1];
if(SamplesToMix && control != 0)
{
LeftVol *= control->channel_volume[0];
RightVol *= control->channel_volume[1];
control->generation = Crunky->generation;
control->last_played_sample_index = clip->at_sample_index;
}
// NOTE(casey): Mix samples
for(u32 SampleIndex = 0;
SampleIndex < SamplesToMix;
++SampleIndex)
{
u32 src_index = 2*(base_sample_index + SampleIndex);
f32 Left = LeftVol *(f32)clip->samples[src_index + 0];
f32 Right = RightVol*(f32)clip->samples[src_index + 1];
u32 dst_index = 2*SampleIndex;
mix_buffer[dst_index + 0] += Left;
mix_buffer[dst_index + 1] += Right;
}
}
}
}
function void
def_audio_mix_destination(i16 *dst, f32 *src, u32 sample_count){
u32 opl = sample_count*2;
for(u32 i = 0; i < opl; i += 1){
f32 sample = src[i];
f32 sat_sample = clamp(-32768.f, sample, 32767.f);
dst[i] = (i16)sat_sample;
}
}
////////////////////////////////
// NOTE(allen): Loading Clip
#if !defined(FCODER_SKIP_WAV)
#define FCODER_SKIP_WAV
#pragma pack(push, 1)
struct wave_fmt_data
{
u16 wFormatTag;
u16 wChannels;
u32 dwSamplesPerSec;
u32 dwAvgBytesPerSec;
u16 wBlockAlign;
u16 wBitsPerSample;
};
struct riff_header
{
u32 ID;
u32 DataSize;
};
#pragma pack(pop)
#endif
function Audio_Clip
audio_clip_from_wav_data(String_Const_u8 data){
Audio_Clip Result = {};
if (data.size >= 4 && *(u32 *)data.str == *(u32 *)"RIFF"){
// NOTE(casey): This ROM is in WAV format
riff_header *RootHeader = (riff_header *)data.str;
wave_fmt_data *Format = 0;
u32 SampleDataSize = 0;
i16 *Samples = 0;
u32 At = sizeof(riff_header);
u32 LastAt = At + ((RootHeader->DataSize + 1) & ~1);
if ((*(u32 *)(data.str + At) == *(u32 *)"WAVE") &&
(LastAt <= data.size)){
At += sizeof(u32);
while (At < LastAt){
riff_header *Header = (riff_header *)(data.str + At);
u32 DataAt = At + sizeof(riff_header);
u32 EndAt = DataAt + ((Header->DataSize + 1) & ~1);
if(EndAt <= data.size)
{
void *Data = (data.str + DataAt);
if(Header->ID == *(u32 *)"fmt ")
{
Format = (wave_fmt_data *)Data;
}
else if(Header->ID == *(u32 *)"data")
{
SampleDataSize = Header->DataSize;
Samples = (i16 *)Data;
}
}
At = EndAt;
}
}
if (Format &&
Samples &&
(Format->wFormatTag == 1) &&
(Format->wChannels == 2) &&
(Format->wBitsPerSample == 16) &&
(Format->dwSamplesPerSec == 48000)){
for (u32 i = 0; i < 2; i += 1){
Result.channel_volume[i] = 1.f;
}
Result.sample_count = SampleDataSize / (Format->wChannels*Format->wBitsPerSample/8);
Result.samples = (i16 *)Samples;
}
else{
// TODO(casey): This is where you would output an error - to 4coder somehow?
}
}
else{
// TODO(casey): This is where you would output an error - to 4coder somehow?
}
return(Result);
}
function Audio_Clip
audio_clip_from_wav_FILE(Arena *arena, FILE *file){
String_Const_u8 data = data_from_file(arena, file);
Audio_Clip result = audio_clip_from_wav_data(data);
return(result);
}
function Audio_Clip
audio_clip_from_wav_file_name(Arena *arena, char *file_name){
Audio_Clip result = {};
String_Const_u8 data = {};
FILE *file = fopen(file_name, "rb");
if (file != 0){
result = audio_clip_from_wav_FILE(arena, file);
fclose(file);
}
return(result);
}

View File

@ -0,0 +1,56 @@
/* date = November 23rd 2020 1:18 pm */
#ifndef FCODER_AUDIO_H
#define FCODER_AUDIO_H
////////////////////////////////
// NOTE(allen): Default Mixer Types
struct Audio_Control{
volatile f32 channel_volume[2];
volatile u32 generation;
volatile u32 last_played_sample_index;
volatile b32 loop;
};
struct Audio_Clip{
i16 *samples;
Audio_Control *control;
f32 channel_volume[2];
u32 sample_count;
u32 at_sample_index;
};
struct Audio_System{
volatile u32 quit;
volatile u32 ticket;
volatile u32 serving;
volatile u32 generation;
Audio_Clip playing_clips[64];
// NOTE(casey): Requests to play sounds are written to a pending array to avoid long locking
volatile u32 pending_clip_count;
Audio_Clip pending_clips[64];
};
////////////////////////////////
// NOTE(allen): Default Mixer
function void def_audio_init(void);
function void def_audio_play_clip(Audio_Clip clip, Audio_Control *control);
function b32 def_audio_is_playing(Audio_Control *control);
function void def_audio_stop(Audio_Control *control);
function void def_audio_mix_sources(void *ctx, f32 *mix_buffer, u32 sample_count);
function void def_audio_mix_destination(i16 *dst, f32 *src, u32 sample_count);
////////////////////////////////
// NOTE(allen): Loading Clip
function Audio_Clip audio_clip_from_wav_data(String_Const_u8 data);
function Audio_Clip audio_clip_from_wav_FILE(Arena *arena, FILE *file);
function Audio_Clip audio_clip_from_wav_file_name(Arena *arena, char *file_name);
#endif //4CODER_AUDIO_H

View File

@ -437,84 +437,14 @@ CUSTOM_DOC("Auto-indents the range between the cursor and the mark.")
move_past_lead_whitespace(app, view, buffer);
}
function i64
get_line_indent_level(Application_Links *app, View_ID view, Buffer_ID buffer, i64 line)
{
Scratch_Block scratch(app);
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
i64 line_start_pos = get_line_start_pos(app, buffer, line);
Range_i64 line_indent_range = Ii64(0, 0);
i64 tabs_at_beginning = 0;
i64 spaces_at_beginning = 0;
for(u64 i = 0; i < line_string.size; i += 1)
{
if(line_string.str[i] == '\t')
{
tabs_at_beginning += 1;
}
else if(character_is_whitespace(line_string.str[i]))
{
spaces_at_beginning += 1;
}
else if(!character_is_whitespace(line_string.str[i]))
{
line_indent_range.max = (i64)i;
break;
}
}
// NOTE(PS): This is in the event that we are unindenting a line that
// is JUST tabs or spaces - rather than unindenting nothing
// and then reindenting the proper amount, this should cause
// the removal of all leading tabs and spaces on an otherwise
// empty line
bool place_cursor_at_end = false;
if (line_indent_range.max == 0 && line_string.size > 0)
{
line_indent_range.max = line_string.size;
place_cursor_at_end = true;
}
Range_i64 indent_range =
{
line_indent_range.min + line_start_pos,
line_indent_range.max + line_start_pos,
};
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
i64 spaces_per_indent_level = indent_width;
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
return indent_level;
}
function String_Const_u8
get_indent_string(Application_Links* app, Arena* scratch)
{
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
String_Const_u8 result;
if (indent_with_tabs) {
result = string_u8_litexpr("\t");
} else {
result = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
}
return result;
}
CUSTOM_COMMAND_SIG(write_text_and_auto_indent)
CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.")
{
ProfileScope(app, "write and auto indent");
Scratch_Block scratch(app);
User_Input in = get_current_input(app);
String_Const_u8 insert = to_writable(&in);
if (insert.str != 0 && insert.size > 0){
b32 do_auto_indent = false;
b32 only_indent_next_line = true;
b32 is_newline = false;
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
switch (insert.str[i]){
case ';': case ':':
@ -522,30 +452,16 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
case '(': case ')':
case '[': case ']':
case '#':
{
do_auto_indent = true;
}break;
case '\n': case '\t':
{
do_auto_indent = true;
is_newline = true;
}break;
}
}
View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer);
String_Const_u8 ext = string_file_extension(file_name);
if (string_match(ext, string_u8_litexpr("js")) ||
string_match(ext, string_u8_litexpr("css")))
{
only_indent_next_line = do_auto_indent;
}
if (do_auto_indent){
History_Group group = history_group_begin(app, buffer);
View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
Range_i64 pos = {};
if (view_has_highlighted_range(app, view)){
pos = get_view_range(app, view);
@ -557,29 +473,11 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
write_text_input(app);
i64 end_pos = view_get_cursor_pos(app, view);
if (!only_indent_next_line) {
pos.min = Min(pos.min, end_pos);
pos.max = Max(pos.max, end_pos);
auto_indent_buffer(app, buffer, pos, 0);
move_past_lead_whitespace(app, view, buffer);
} else if (only_indent_next_line && is_newline) {
String_Const_u8 indent_string = get_indent_string(app, scratch);
pos.min = Min(pos.min, end_pos);
pos.max = Max(pos.max, end_pos);
// getting the indent from the PREVIOUS line, not the line
// the cursor is about to be on - since that line is new,
// and therefore, empty
i64 line = get_line_number_from_pos(app, buffer, pos.min);
i64 indent_level = get_line_indent_level(app, view, buffer, line);
pos.min = pos.max = end_pos;
for(i64 i = 0; i < indent_level; i += 1)
{
buffer_replace_range(app, buffer, Ii64(pos.max), indent_string);
}
move_past_lead_whitespace(app, view, buffer);
}
history_group_end(group);
auto_indent_buffer(app, buffer, pos, 0);
move_past_lead_whitespace(app, view, buffer);
}
else{
write_text_input(app);

View File

@ -159,139 +159,6 @@ CUSTOM_DOC("Delete characters between the cursor position and the first alphanum
push_boundary_list(scratch, boundary_alpha_numeric_unicode));
}
function i64
get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
Side side, Scan_Direction direction, i64 pos)
{
// NOTE(PS): originally this was F4_Boundary_TokenAndWhitespace
i64 result = boundary_non_whitespace(app, buffer, side, direction, pos);
Token_Array tokens = get_token_array_from_buffer(app, buffer);
if (tokens.tokens != 0){
switch (direction){
case Scan_Forward:
{
i64 buffer_size = buffer_get_size(app, buffer);
result = buffer_size;
if(tokens.count > 0)
{
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
Token *token = token_it_read(&it);
if(token == 0)
{
break;
}
// NOTE(rjf): Comments/Strings
if(token->kind == TokenBaseKind_Comment ||
token->kind == TokenBaseKind_LiteralString)
{
result = boundary_non_whitespace(app, buffer, side, direction, pos);
break;
}
// NOTE(rjf): All other cases.
else
{
if (token->kind == TokenBaseKind_Whitespace)
{
// token_it_inc_non_whitespace(&it);
// token = token_it_read(&it);
}
if (side == Side_Max){
result = token->pos + token->size;
token_it_inc_all(&it);
Token *ws = token_it_read(&it);
if(ws != 0 && ws->kind == TokenBaseKind_Whitespace &&
get_line_number_from_pos(app, buffer, ws->pos + ws->size) ==
get_line_number_from_pos(app, buffer, token->pos))
{
result = ws->pos + ws->size;
}
}
else{
if (token->pos <= pos){
token_it_inc_non_whitespace(&it);
token = token_it_read(&it);
}
if (token != 0){
result = token->pos;
}
}
}
}
}break;
case Scan_Backward:
{
result = 0;
if (tokens.count > 0){
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
Token *token = token_it_read(&it);
Token_Iterator_Array it2 = it;
token_it_dec_non_whitespace(&it2);
Token *token2 = token_it_read(&it2);
// NOTE(rjf): Comments/Strings
if(token->kind == TokenBaseKind_Comment ||
token->kind == TokenBaseKind_LiteralString ||
(token2 &&
token2->kind == TokenBaseKind_Comment ||
token2->kind == TokenBaseKind_LiteralString))
{
result = boundary_non_whitespace(app, buffer, side, direction, pos);
break;
}
if (token->kind == TokenBaseKind_Whitespace){
token_it_dec_non_whitespace(&it);
token = token_it_read(&it);
}
if (token != 0){
if (side == Side_Min){
if (token->pos >= pos){
token_it_dec_non_whitespace(&it);
token = token_it_read(&it);
}
result = token->pos;
}
else{
if (token->pos + token->size >= pos){
token_it_dec_non_whitespace(&it);
token = token_it_read(&it);
}
result = token->pos + token->size;
}
}
}
}break;
}
}
return(result);
}
CUSTOM_COMMAND_SIG(backspace_alpha_numeric_or_camel_boundary)
CUSTOM_DOC("Deletes left to a alphanumeric or camel boundary.")
{
Scratch_Block scratch(app);
current_view_boundary_delete(app, Scan_Backward, push_boundary_list(scratch,
boundary_line,
boundary_alpha_numeric,
boundary_alpha_numeric_camel));
}
CUSTOM_COMMAND_SIG(backspace_token_boundary)
CUSTOM_DOC("Deletes left to a token boundary.")
{
Scratch_Block scratch(app);
Boundary_Function_List boundary_list = push_boundary_list(scratch, get_boundary_token_or_whitespace);
current_view_boundary_delete(app, Scan_Backward, boundary_list);
}
CUSTOM_COMMAND_SIG(delete_alpha_numeric_boundary)
CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the right.")
{
@ -1706,31 +1573,6 @@ CUSTOM_DOC("Delete the line the on which the cursor sits.")
buffer_replace_range(app, buffer, range, string_u8_litexpr(""));
}
CUSTOM_COMMAND_SIG(delete_to_end_of_line)
CUSTOM_DOC("Deletes all text from the cursor to the end of the line")
{
View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
i64 pos = view_get_cursor_pos(app, view);
i64 line_number = get_line_number_from_pos(app, buffer, pos);
Range_Cursor line_range = get_line_range(app, buffer, line_number);
Range_i64 delete_range = {};
if (line_range.start.line != 0 && line_range.end.line != 0)
{
delete_range = Ii64(pos, line_range.end.pos);
}
if (range_size(delete_range) == 0)
{
delete_range.end += 1;
i32 buffer_size = (i32)buffer_get_size(app, buffer);
delete_range.end = clamp_top(delete_range.end, buffer_size);
}
buffer_replace_range(app, buffer, delete_range, string_u8_litexpr(""));
}
////////////////////////////////
CUSTOM_COMMAND_SIG(open_file_in_quotes)
@ -2235,284 +2077,5 @@ CUSTOM_DOC("Notes the external modification of attached files by printing a mess
}
}
CUSTOM_COMMAND_SIG(toggle_compilation_view)
{
Buffer_ID buffer = view_get_buffer(app, global_compilation_view, Access_Always);
Face_ID face_id = get_face_id(app, buffer);
Face_Metrics metrics = get_face_metrics(app, face_id);
if(global_compilation_view_expanded ^= 1)
{
view_set_split_pixel_size(app, global_compilation_view, (i32)(metrics.line_height*32.f));
}
else
{
view_set_split_pixel_size(app, global_compilation_view, (i32)(metrics.line_height*4.f));
}
}
////////////////////////////////////////
// Indentation
function void
reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_delta)
{
Scratch_Block scratch(app);
View_ID view = get_active_view(app, Access_ReadWriteVisible);
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
i64 line_start_pos = get_line_start_pos(app, buffer, line);
Range_i64 line_indent_range = Ii64(0, 0);
i64 tabs_at_beginning = 0;
i64 spaces_at_beginning = 0;
for(u64 i = 0; i < line_string.size; i += 1)
{
if(line_string.str[i] == '\t')
{
tabs_at_beginning += 1;
}
else if(character_is_whitespace(line_string.str[i]))
{
spaces_at_beginning += 1;
}
else if(!character_is_whitespace(line_string.str[i]))
{
line_indent_range.max = (i64)i;
break;
}
}
// NOTE(PS): This is in the event that we are unindenting a line that
// is JUST tabs or spaces - rather than unindenting nothing
// and then reindenting the proper amount, this should cause
// the removal of all leading tabs and spaces on an otherwise
// empty line
bool place_cursor_at_end = false;
if (line_indent_range.max == 0 && line_string.size == (u64)(spaces_at_beginning + tabs_at_beginning))
{
line_indent_range.max = line_string.size;
place_cursor_at_end = true;
}
// NOTE(rjf): Indent lines.
{
Range_i64 indent_range =
{
line_indent_range.min + line_start_pos,
line_indent_range.max + line_start_pos,
};
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
i64 spaces_per_indent_level = indent_width;
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
i64 new_indent_level = indent_level + indent_delta;
String_Const_u8 indent_string;
if (indent_with_tabs) {
indent_string = str8_lit("\t");
} else {
indent_string = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
}
buffer_replace_range(app, buffer, indent_range, str8_lit(""));
for(i64 i = 0; i < new_indent_level; i += 1)
{
buffer_replace_range(app, buffer, Ii64(line_start_pos), indent_string);
}
if (place_cursor_at_end)
{
// update line_string now that we've edited the line
line_string = push_buffer_line(app, scratch, buffer, line);
line_start_pos = get_line_start_pos(app, buffer, line);
i64 line_end_pos = line_start_pos + line_string.size;
view_set_cursor(app, view, seek_pos(line_end_pos));
}
}
}
internal void
reindent_line_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i64 indent_delta)
{
for(i64 i = range.min; i <= range.max; i += 1)
{
reindent_line(app, buffer, i, indent_delta);
}
}
// TODO(PS): @F4Layer - it's unclear why we need these, when there's existing, similarly named functions
// already in the codebase. (Just remove the f4_ and the compiler will show you where).
internal Range_i64
f4_get_line_range_from_pos_range(Application_Links *app, Buffer_ID buffer, Range_i64 pos_range)
{
Range_i64 lines_range =
Ii64(get_line_number_from_pos(app, buffer, pos_range.min),
get_line_number_from_pos(app, buffer, pos_range.max));
return lines_range;
}
// TODO(PS): @F4Layer
internal Range_i64
f4_get_pos_range_from_line_range(Application_Links *app, Buffer_ID buffer, Range_i64 line_range)
{
if(line_range.min > line_range.max)
{
i64 swap = line_range.max;
line_range.max = line_range.min;
line_range.min = swap;
}
Range_i64 pos_range =
Ii64(get_line_start_pos(app, buffer, line_range.min),
get_line_end_pos(app, buffer, line_range.max));
return pos_range;
}
internal void
reindent_pos_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i64 indent_delta)
{
reindent_line_range(app, buffer,
f4_get_line_range_from_pos_range(app, buffer, range),
indent_delta);
}
CUSTOM_COMMAND_SIG(unindent_line)
{
View_ID view = get_active_view(app, Access_ReadWrite);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
i64 pos = view_get_cursor_pos(app, view);
i64 line = get_line_number_from_pos(app, buffer, pos);
reindent_line(app, buffer, line, -1);
}
internal void
adjust_cursor_and_mark_for_indentation(Application_Links *app, View_ID view, i64 original_cursor, i64 original_mark, Range_i64 original_line_range)
{
Buffer_ID buffer = view_get_buffer(app, view, Access_Read);
Scratch_Block scratch(app);
if(original_cursor == original_mark)
{
i64 start_pos = get_line_start_pos(app, buffer, original_line_range.min);
i64 new_pos = start_pos;
String_Const_u8 line = push_buffer_line(app, scratch, buffer, original_line_range.min);
for(u64 i = 0; i < line.size; i += 1)
{
if(!character_is_whitespace(line.str[i]))
{
new_pos = start_pos + (i64)i;
break;
}
}
view_set_cursor(app, view, seek_pos(new_pos));
view_set_mark(app, view, seek_pos(new_pos));
}
else
{
Range_i64 range = f4_get_pos_range_from_line_range(app, buffer, original_line_range);
view_set_cursor(app, view, seek_pos(original_cursor > original_mark ? range.max : range.min));
view_set_mark(app, view, seek_pos(original_cursor > original_mark ? range.min : range.max));
}
}
function void
update_range_indentation(Application_Links* app, i32 indent_offset)
{
Scratch_Block scratch(app);
View_ID view = get_active_view(app, Access_ReadWrite);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWrite);
i64 pos = view_get_cursor_pos(app, view);
i64 mark = view_get_mark_pos(app, view);
Range_i64 pos_range = Ii64(pos, mark);
Range_i64 line_range = get_line_range_from_pos_range(app, buffer, pos_range);
History_Group group = history_group_begin(app, buffer);
reindent_pos_range(app, buffer, Ii64(pos, mark), indent_offset);
adjust_cursor_and_mark_for_indentation(app, view, pos, mark, line_range);
history_group_end(group);
no_mark_snap_to_cursor(app, view);
}
CUSTOM_COMMAND_SIG(indent_range)
{
update_range_indentation(app, 1);
}
CUSTOM_COMMAND_SIG(unindent_range)
{
update_range_indentation(app, -1);
}
CUSTOM_COMMAND_SIG(indent_or_autocomplete)
{
Scratch_Block scratch(app);
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer != 0)
{
i64 pos = view_get_cursor_pos(app, view);
Buffer_Cursor buffer_cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
Buffer_Cursor line_start_cursor = get_line_start(app, buffer, buffer_cursor.line);
u8 char_before = buffer_get_char(app, buffer, pos - 1);
if ((buffer_cursor.pos == line_start_cursor.pos) || character_is_whitespace(char_before))
{
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
String_Const_u8 indent_string;
if (indent_with_tabs) {
indent_string = str8_lit("\t");
} else {
indent_string = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
}
write_text(app, indent_string);
}
else
{
word_complete(app);
}
}
}
///////////////////////////////////////////
CUSTOM_COMMAND_SIG(input_enter_behavior)
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer == 0)
{
buffer = view_get_buffer(app, view, Access_ReadVisible);
if (buffer != 0)
{
goto_jump_at_cursor(app);
lock_jump_buffer(app, buffer);
}
}
else
{
leave_current_input_unhandled(app);
}
}
CUSTOM_COMMAND_SIG(input_alt_enter_behavior)
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer == 0){
buffer = view_get_buffer(app, view, Access_ReadVisible);
if (buffer != 0){
goto_jump_at_cursor_same_panel(app);
lock_jump_buffer(app, buffer);
}
}
else
{
leave_current_input_unhandled(app);
}
}
// BOTTOM

View File

@ -4990,27 +4990,6 @@ string_find_first_insensitive(String_Const_u32 str, String_Const_u32 needle){
return(string_find_first(str, needle, StringMatch_CaseInsensitive));
}
function u64
string_find_first_of_set(String_Const_u8 str, String_Const_u8 needle)
{
u64 i = 0;
if (needle.size > 0){
i = 0;
for (;i < str.size; i += 1){
bool found = false;
for (u64 j = 0; j < needle.size; j++)
{
if (str.str[i] == needle.str[j]) {
found = true;
break;
}
}
if (found) break;
}
}
return(i);
}
function b32
string_has_substr(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule rule){
return(string_find_first(str, needle, rule) < str.size);

View File

@ -95,95 +95,5 @@ CUSTOM_DOC("Jump to the first definition in the code index matching an identifie
}
}
global String_Const_u8 code_index_note_strs[] = {
str8_lit("Type"),
str8_lit("Function"),
str8_lit("Macro"),
str8_lit("None"),
};
function bool
note_is_of_kind(Code_Index_Note_Kind* kinds, i32 kinds_count, Code_Index_Note* note)
{
bool result = false;
for (i32 i = 0; i < kinds_count; i++)
{
if (kinds[i] == note->note_kind)
{
result = true;
break;
}
}
return result;
}
function void
lister_add_from_buffer_code_index_filtered(Lister* lister, Buffer_ID buffer, Arena* scratch, Code_Index_Note_Kind* kinds, i32 kinds_count, bool filter_all_but_last)
{
Code_Index_File* file_notes = code_index_get_file(buffer);
if (!file_notes) return;
for (Code_Index_Note* note = file_notes->note_list.first;
note != 0;
note = note->next)
{
if (!note_is_of_kind(kinds, kinds_count, note)) continue;
if (filter_all_but_last && note->next_in_hash) continue;
String_Const_u8 sort = code_index_note_strs[note->note_kind];
Tiny_Jump *jump = push_array(scratch, Tiny_Jump, 1);
jump->buffer = buffer;
jump->pos = note->pos.start;
lister_add_item(lister, note->text, sort, jump, 0);
}
}
function void
run_jump_lister(Application_Links* app, Lister* lister)
{
Lister_Result l_result = run_lister(app, lister);
Tiny_Jump result = {};
if (!l_result.canceled && l_result.user_data != 0){
block_copy_struct(&result, (Tiny_Jump*)l_result.user_data);
}
if (result.buffer != 0)
{
View_ID view = get_this_ctx_view(app, Access_Always);
point_stack_push_view_cursor(app, view);
jump_to_location(app, view, result.buffer, result.pos);
}
}
function void
lister_search_filtered(Application_Links* app, char* query, Code_Index_Note_Kind* allowed, i32 allowed_count, bool filter_all_but_last)
{
Scratch_Block scratch(app);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister_set_default_handlers(lister);
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);
buffer != 0; buffer = get_buffer_next(app, buffer, Access_Always))
{
lister_add_from_buffer_code_index_filtered(lister, buffer, scratch, allowed, allowed_count, filter_all_but_last);
}
run_jump_lister(app, lister);
}
CUSTOM_UI_COMMAND_SIG(lister_search_all)
CUSTOM_DOC("Runs a search lister on all code indices of the project")
{
char *query = "Search:";
Code_Index_Note_Kind allowed[] = {
CodeIndexNote_Macro,
CodeIndexNote_Function,
CodeIndexNote_Type,
};
lister_search_filtered(app, query, allowed, 3, false);
}
// BOTTOM

View File

@ -296,6 +296,7 @@ map_get_binding_non_recursive(Command_Map *map, Input_Event *event, Binding_Matc
}
}
}break;
case BindingMatchRule_Loose:
{
for (SNode *node = list->first;
@ -309,7 +310,7 @@ map_get_binding_non_recursive(Command_Map *map, Input_Event *event, Binding_Matc
}
}
}break;
}
}
done:;
}
else{

View File

@ -39,7 +39,8 @@ def_search_normal_fopen(Arena *arena, char *file_name, char *opt){
// NOTE(allen): Extension List
function String_Const_u8_Array
parse_extension_line_to_extension_list(Arena *arena, String_Const_u8 str){
parse_extension_line_to_extension_list(Application_Links *app, Arena *arena, String_Const_u8 str){
ProfileScope(app, "parse extension line to extension list");
i32 count = 0;
for (u64 i = 0; i < str.size; i += 1){
if (str.str[i] == '.'){
@ -64,13 +65,6 @@ parse_extension_line_to_extension_list(Arena *arena, String_Const_u8 str){
return(array);
}
function String_Const_u8_Array
parse_extension_line_to_extension_list(Application_Links *app, Arena *arena, String_Const_u8 str){
ProfileScope(app, "parse extension line to extension list");
return parse_extension_line_to_extension_list(arena, str);
}
////////////////////////////////
// NOTE(allen): Token Array

View File

@ -15,276 +15,15 @@
#include "generated/managed_id_metadata.cpp"
#endif
#define EXTERNAL_KEYBOARD 0
#if OS_MAC && !EXTERNAL_KEYBOARD
global u32 key_alt = KeyCode_Command;
#else
global u32 key_alt = KeyCode_Alt;
#endif
function String_Const_u8
get_lexeme_under_cursor(Application_Links* app, View_ID view, Buffer_ID buffer, Arena* arena)
{
String_Const_u8 lexeme = {0};
i64 pos = view_get_cursor_pos(app, view);
Token* token = get_token_from_pos(app, buffer, pos);
if (token != 0) {
lexeme = push_token_lexeme(app, arena, buffer, token);
}
return lexeme;
}
function void
go_to_definition(Application_Links* app, String_Const_u8 lexeme, View_ID view)
{
Code_Index_Note* note = 0;
// if we're trying to go to the definition of the same lexeme as last time
// then there are probably a typedef + declaration in different locations so
// we want to advance to the next code index note that matches this lexeme
// and then loop
if (string_match(go_to_definition_last_lexeme, lexeme))
{
Code_Index_Note_List* list = code_index__list_from_string(lexeme);
u64 i = 0;
for (Code_Index_Note *it = list->first;
it != 0;
it = it->next_in_hash, i++){
if (string_match(lexeme, it->text) && i > go_to_definition_last_lexeme_index){
note = it;
go_to_definition_last_lexeme_index = i;
break;
}
}
}
if (!note)
{
note = code_index_note_from_string(lexeme);
go_to_definition_last_lexeme = lexeme;
go_to_definition_last_lexeme_index = 0;
}
if (note == 0) return;
Buffer_ID buffer = note->file->buffer;
view_set_buffer(app, view, buffer, 0);
switch (note->note_kind)
{
case CodeIndexNote_Type:
case CodeIndexNote_Function:
case CodeIndexNote_Macro:
{
jump_to_location(app, view, note->file->buffer, note->pos.start);
} break;
default: {} break;
}
}
CUSTOM_COMMAND_SIG(cmd_enter_behavior)
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer == 0){
buffer = view_get_buffer(app, view, Access_ReadVisible);
if (buffer != 0){
goto_jump_at_cursor(app);
lock_jump_buffer(app, buffer);
}
}
else{
Scratch_Block scratch(app);
String_Const_u8 lexeme = get_lexeme_under_cursor(app, view, buffer, scratch);
if (lexeme.size > 0) {
go_to_definition(app, lexeme, view);
}
}
}
CUSTOM_COMMAND_SIG(cmd_alt_enter_behavior)
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer == 0){
buffer = view_get_buffer(app, view, Access_ReadVisible);
if (buffer != 0){
goto_jump_at_cursor_same_panel(app);
lock_jump_buffer(app, buffer);
}
}
else{
Scratch_Block scratch(app);
String_Const_u8 lexeme = get_lexeme_under_cursor(app, view, buffer, scratch);
if (lexeme.size > 0) {
view = get_next_view_looped_primary_panels(app, view, Access_Always);
go_to_definition(app, lexeme, view);
}
}
}
function void
bindings_cmd_misc(Mapping* m, Command_Map* map)
{
Bind(command_lister, KeyCode_W);
Bind(change_active_panel, KeyCode_E);
Bind(toggle_compilation_view, KeyCode_Minus);
}
function void
bindings_cmd_file_ops(Mapping* m, Command_Map* map)
{
Bind(set_mark, KeyCode_Space);
Bind(interactive_open_or_new, KeyCode_Comma);
Bind(interactive_switch_buffer, KeyCode_Period);
Bind(save, KeyCode_Semicolon);
}
function void
bindings_cmd_search(Mapping* m, Command_Map* map)
{
Bind(query_replace, KeyCode_S);
Bind(search, KeyCode_F);
Bind(list_all_locations_of_identifier, KeyCode_D);
Bind(list_all_substring_locations_case_insensitive, KeyCode_D, key_alt);
Bind(goto_next_jump, KeyCode_T);
Bind(goto_prev_jump, KeyCode_R);
// Listers
Bind(lister_search_all, KeyCode_1);
}
function void
bindings_cmd_nav(Mapping* m, Command_Map* map)
{
Bind(seek_beginning_of_line, KeyCode_Y);
Bind(seek_end_of_line, KeyCode_P);
Bind(move_left_token_boundary, KeyCode_U);
Bind(move_right_token_boundary, KeyCode_O);
Bind(move_up, KeyCode_I);
Bind(move_left, KeyCode_J);
Bind(move_down, KeyCode_K);
Bind(move_right, KeyCode_L);
Bind(move_up_to_blank_line_end, KeyCode_H);
Bind(move_down_to_blank_line_end, KeyCode_N);
Bind(cmd_enter_behavior, KeyCode_Return);
Bind(cmd_alt_enter_behavior, KeyCode_Return, key_alt);
Bind(jump_to_last_point, KeyCode_Semicolon, KeyCode_Control);
}
function void
custom_keyboard_bindings()
{
modal_set_cursor_color_u32(modal_mode_input, 0xFF00FF00);
modal_set_cursor_color_u32(modal_mode_cmd, 0xFFFF0000);
modal_set_cursor_color_u32(modal_mode_debug, 0xFF00F0FF);
MappingScope();
// Global commands
modal_bind_all(modal_map_id_global, modal_set_mode_toggle, KeyCode_F, key_alt, 0);
modal_bind_all(modal_map_id_global, modal_set_mode_next, KeyCode_F, KeyCode_Control, 0);
modal_bind_all(modal_map_id_global, exit_4coder, KeyCode_F4, key_alt, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F1, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F2, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F3, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F4, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F5, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F6, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F7, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F8, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F9, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F10, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F11, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F12, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F13, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F14, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F15, 0, 0);
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F16, 0, 0);
SelectMapping(&modal_get_mode(modal_mode_cmd)->map);
SelectMap(modal_map_id_global);
{
bindings_cmd_file_ops(m, map);
bindings_cmd_misc(m, map);
bindings_cmd_search(m, map);
bindings_cmd_nav(m, map);
// Text Editing
Bind(delete_to_end_of_line, KeyCode_A);
Bind(undo, KeyCode_Z);
Bind(redo, KeyCode_B);
Bind(copy, KeyCode_C);
Bind(paste, KeyCode_V);
Bind(cut, KeyCode_X);
Bind(backspace_char, KeyCode_Backspace);
Bind(backspace_alpha_numeric_or_camel_boundary, KeyCode_Backspace, key_alt);
Bind(backspace_token_boundary, KeyCode_Backspace, KeyCode_Control);
Bind(unindent_range, KeyCode_Tab, KeyCode_Shift);
Bind(indent_range, KeyCode_Tab);
// Macros
Bind(keyboard_macro_start_recording, KeyCode_1, key_alt);
Bind(keyboard_macro_finish_recording, KeyCode_2, key_alt);
Bind(keyboard_macro_replay, KeyCode_3, key_alt);
// Yeet Sheet
Bind(loco_yeet_selected_range_or_jump, KeyCode_G);
}
SelectMapping(&modal_get_mode(modal_mode_input)->map);
SelectMap(modal_map_id_global);
{
BindMouse(click_set_cursor_and_mark, MouseCode_Left);
BindMouseRelease(click_set_cursor, MouseCode_Left);
BindCore(click_set_cursor_and_mark, CoreCode_ClickActivateView);
BindMouseMove(click_set_cursor_if_lbutton);
Bind(delete_char, KeyCode_Delete);
Bind(backspace_char, KeyCode_Backspace);
Bind(backspace_alpha_numeric_or_camel_boundary, KeyCode_Backspace, key_alt);
Bind(backspace_token_boundary, KeyCode_Backspace, KeyCode_Control);
Bind(move_up, KeyCode_I, key_alt);
Bind(move_down, KeyCode_K, key_alt);
BindTextInput(write_text_and_auto_indent);
Bind(indent_or_autocomplete, KeyCode_Tab);
Bind(unindent_line, KeyCode_Tab, KeyCode_Shift);
Bind(write_todo, KeyCode_T, key_alt);
Bind(write_note, KeyCode_G, key_alt);
Bind(input_enter_behavior, KeyCode_Return);
Bind(input_alt_enter_behavior, KeyCode_Return, key_alt);
}
SelectMapping(&modal_get_mode(modal_mode_debug)->map);
SelectMap(modal_map_id_global);
{
bindings_cmd_file_ops(m, map);
bindings_cmd_misc(m, map);
bindings_cmd_search(m, map);
bindings_cmd_nav(m, map);
}
}
void
custom_layer_init(Application_Links *app){
Thread_Context *tctx = get_thread_context(app);
// NOTE(allen): setup for default framework
default_framework_init(app);
// NOTE(allen): default hooks and command maps
set_all_default_hooks(app);
modal_init(3, tctx);
custom_keyboard_bindings();
#if 0
mapping_init(tctx, &framework_mapping);
String_ID global_map_id = vars_save_string_lit("keys_global");
String_ID file_map_id = vars_save_string_lit("keys_file");
@ -295,8 +34,6 @@ custom_layer_init(Application_Links *app){
setup_default_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
#endif
setup_essential_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
#endif
}
#endif //FCODER_DEFAULT_BINDINGS

View File

@ -45,10 +45,6 @@ CUSTOM_ID(colors, defcolor_back_cycle);
CUSTOM_ID(colors, defcolor_text_cycle);
CUSTOM_ID(colors, defcolor_line_numbers_back);
CUSTOM_ID(colors, defcolor_line_numbers_text);
CUSTOM_ID(colors, defcolor_function);
CUSTOM_ID(colors, defcolor_operator);
CUSTOM_ID(colors, defcolor_type);
CUSTOM_ID(colors, defcolor_macro);
struct Color_Table_Node{
Color_Table_Node *next;

View File

@ -58,8 +58,7 @@ global b32 auto_center_after_jumps = AUTO_CENTER_AFTER_JUMPS;
global u8 locked_buffer_space[256];
global String_Const_u8 locked_buffer = {};
global View_ID global_compilation_view = 0;
global b32 global_compilation_view_expanded = 0;
global View_ID build_footer_panel_view_id = 0;
global u8 out_buffer_space[1024];
@ -112,31 +111,5 @@ global Point_Stack point_stack = {};
global Clipboard clipboard0 = {};
////////////////////////////////
// Modal System Maps
global String_ID modal_map_id_global;
global String_ID modal_map_id_file;
global String_ID modal_map_id_code;
// Modal system modes
global Modal_Mode* modal_modes;
global u32 modal_modes_cap;
// State Tracking
global u32 modal_last_mode;
global u32 modal_curr_mode;
// Mode Ids
global u32 modal_mode_input = 0;
global u32 modal_mode_cmd = 1;
global u32 modal_mode_debug = 2;
////////////////////////////////
static String_Const_u8 go_to_definition_last_lexeme = {};
static u64 go_to_definition_last_lexeme_index = 0;
// BOTTOM

View File

@ -13,51 +13,21 @@ CUSTOM_DOC("Default command for responding to a startup event")
String_Const_u8_Array file_names = input.event.core.file_names;
load_themes_default_folder(app);
default_4coder_initialize(app, file_names);
default_4coder_side_by_side_panels(app, file_names);
b32 auto_load = def_get_config_b32(vars_save_string_lit("automatically_load_project"));
if (auto_load){
load_project(app);
}
}
// Setup Default Layout
Buffer_ID comp_buffer = create_buffer(app, str8_lit("*compilation*"), BufferCreate_NeverAttachToFile | BufferCreate_AlwaysNew);
buffer_set_setting(app, comp_buffer, BufferSetting_Unimportant, true);
buffer_set_setting(app, comp_buffer, BufferSetting_ReadOnly, true);
Buffer_Identifier comp_name = buffer_identifier(str8_lit("*compilation*"));
Buffer_Identifier code_left_name = buffer_identifier(str8_lit("*scratch*"));
Buffer_Identifier code_right_name = buffer_identifier(str8_lit("*messages*"));
Buffer_ID comp_id = buffer_identifier_to_id(app, comp_name);
Buffer_ID code_left_id = buffer_identifier_to_id(app, code_left_name);
Buffer_ID code_right_id = buffer_identifier_to_id(app, code_right_name);
// Left Panel
View_ID left_view = get_active_view(app, Access_Always);
new_view_settings(app, left_view);
view_set_buffer(app, left_view, code_left_id, 0);
// Bottom panel
View_ID compilation_view = 0;
compilation_view = open_view(app, left_view, ViewSplit_Bottom);
new_view_settings(app, compilation_view);
Buffer_ID buffer = view_get_buffer(app, compilation_view, Access_Always);
Face_ID face_id = get_face_id(app, buffer);
Face_Metrics metrics = get_face_metrics(app, face_id);
view_set_split_pixel_size(app, compilation_view, (i32)(metrics.line_height*4.f));
view_set_passive(app, compilation_view, true);
global_compilation_view = compilation_view;
view_set_buffer(app, compilation_view, comp_id, 0);
// Right Panel
view_set_active(app, left_view);
open_panel_vsplit(app);
View_ID right_view = get_active_view(app, Access_Always);
view_set_buffer(app, right_view, code_right_id, 0);
view_set_active(app, left_view);
{
def_audio_init();
}
{
def_enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace"));
clear_all_layouts(app);
}
system_set_fullscreen(false);
}
CUSTOM_COMMAND_SIG(default_try_exit)
@ -95,9 +65,7 @@ default_implicit_map(Application_Links *app, String_ID lang, String_ID mode, Inp
View_ID view = get_this_ctx_view(app, Access_Always);
Command_Map_ID map_id = default_get_map_id(app, view);
Modal_Mode* mode_curr = modal_get_mode_curr();
Mapping* mode_map = &mode_curr->map;
Command_Binding binding = map_get_binding_recursive(mode_map, map_id, event);
Command_Binding binding = map_get_binding_recursive(&framework_mapping, map_id, event);
// TODO(allen): map_id <-> map name?
result.map = 0;
@ -116,6 +84,7 @@ CUSTOM_DOC("Input consumption loop for default view behavior")
Managed_Scope scope = view_get_managed_scope(app, view);
for (;;){
// NOTE(allen): Get input
User_Input input = get_next_input(app, EventPropertyGroup_Any, 0);
if (input.abort){
break;
@ -184,42 +153,30 @@ code_index_update_tick(Application_Links *app){
buffer_modified_set_clear();
}
f32 time_since_last_dirty_buffers_check = 0;
function void
reload_clean_buffers_on_filesystem_change(Application_Links *app, Frame_Info frame_info)
{
time_since_last_dirty_buffers_check += frame_info.literal_dt;
if (time_since_last_dirty_buffers_check > 1)
{
time_since_last_dirty_buffers_check = 0;
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);
buffer != 0;
buffer = get_buffer_next(app, buffer, Access_Always)) {
Dirty_State dirty = buffer_get_dirty_state(app, buffer);
if (dirty == DirtyState_UnloadedChanges) {
buffer_reopen(app, buffer, 0);
}
}
}
}
function void
default_tick(Application_Links *app, Frame_Info frame_info){
////////////////////////////////
// NOTE(allen): Update code index
code_index_update_tick(app);
////////////////////////////////
// NOTE(allen): Update fade ranges
if (tick_all_fade_ranges(app, frame_info.animation_dt)){
animate_in_n_milliseconds(app, 0);
}
{ // Clear layouts if virtual whitespace setting changed
////////////////////////////////
// NOTE(allen): Clear layouts if virtual whitespace setting changed.
{
b32 enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace"));
if (enable_virtual_whitespace != def_enable_virtual_whitespace){
def_enable_virtual_whitespace = enable_virtual_whitespace;
clear_all_layouts(app);
}
}
reload_clean_buffers_on_filesystem_change(app, frame_info);
}
function Rect_f32
@ -339,55 +296,26 @@ default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id,
draw_comment_highlights(app, buffer, text_layout_id, &token_array, pairs, ArrayCount(pairs));
}
#if 0
// TODO(allen): Put in 4coder_draw.cpp
// NOTE(allen): Color functions
Scratch_Block scratch(app);
ARGB_Color color_function = fcolor_resolve(fcolor_id(defcolor_function));
ARGB_Color color_operator = fcolor_resolve(fcolor_id(defcolor_operator));
ARGB_Color color_type = fcolor_resolve(fcolor_id(defcolor_type));
ARGB_Color color_macro = fcolor_resolve(fcolor_id(defcolor_macro));
Scratch_Block scratch(app);
ARGB_Color argb = 0xFFFF00FF;
Token_Iterator_Array it = token_iterator_pos(0, &token_array, visible_range.first);
for (;;){
if (!token_it_inc_non_whitespace(&it)){
break;
}
Token *token = token_it_read(&it);
String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token);
Code_Index_Note *note = code_index_note_from_string(lexeme);
if (note != 0)
{
switch (note->note_kind)
{
case CodeIndexNote_Type:
{
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), color_type);
} break;
case CodeIndexNote_Function:
{
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), color_function);
} break;
case CodeIndexNote_Macro:
{
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), color_macro);
} break;
default: {} break;
if (!token_it_inc_non_whitespace(&it)){
break;
}
Token *token = token_it_read(&it);
String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token);
Code_Index_Note *note = code_index_note_from_string(lexeme);
if (note != 0 && note->note_kind == CodeIndexNote_Function){
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), argb);
}
}
else if (token->kind == TokenBaseKind_Operator ||
token->kind == TokenBaseKind_ScopeOpen ||
token->kind == TokenBaseKind_ScopeClose ||
token->kind == TokenBaseKind_ParentheticalOpen ||
token->kind == TokenBaseKind_ParentheticalClose ||
token->kind == TokenBaseKind_StatementClose)
{
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), color_operator);
}
}
#endif
}
else{
paint_text_color_fcolor(app, text_layout_id, visible_range, fcolor_id(defcolor_text_default));
@ -555,14 +483,33 @@ default_render_caller(Application_Links *app, Frame_Info frame_info, View_ID vie
// NOTE(allen): draw the buffer
default_render_buffer(app, view_id, face_id, buffer, text_layout_id, region);
loco_render_buffer(app, view_id, face_id, buffer, text_layout_id, region, frame_info);
text_layout_free(app, text_layout_id);
draw_set_clip(app, prev_clip);
}
function void
default_whole_screen_render_caller(Application_Links *app, Frame_Info frame_info){}
default_whole_screen_render_caller(Application_Links *app, Frame_Info frame_info){
#if 0
Rect_f32 region = global_get_screen_rectangle(app);
Vec2_f32 center = rect_center(region);
Face_ID face_id = get_face_id(app, 0);
Scratch_Block scratch(app);
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
SCu8("Hello, World!"), center - V2f32(200.f, 300.f),
0, V2f32(0.f, -1.f));
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
SCu8("Hello, World!"), center - V2f32(240.f, 300.f),
0, V2f32(0.f, 1.f));
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
SCu8("Hello, World!"), center - V2f32(400.f, 400.f),
0, V2f32(-1.f, 0.f));
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
SCu8("Hello, World!"), center - V2f32(400.f, -100.f),
0, V2f32(cos_f32(pi_f32*.333f), sin_f32(pi_f32*.333f)));
#endif
}
HOOK_SIG(default_view_adjust){
// NOTE(allen): Called whenever the view layout/sizes have been modified,
@ -682,70 +629,6 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
}
}
BUFFER_NAME_RESOLVER_SIG(gs_buffer_name_resolution)
{
if (conflict_count <= 1) return;
Scratch_Block scratch(app);
Variable_Handle prj_var = vars_read_key(vars_get_root(), vars_save_string_lit("prj_config"));
String8 prj_dir = prj_path_from_project(scratch, prj_var);
u8 path_divider = '\\';
u64 prj_dir_slash_index = string_find_first_slash(prj_dir);
if (prj_dir_slash_index < prj_dir.size) path_divider = prj_dir.str[prj_dir_slash_index];
for (int i = 0; i < conflict_count; i++)
{
Buffer_Name_Conflict_Entry *conflict = &conflicts[i];
String_Const_u8 file_name = conflict->file_name;
String_Const_u8 uniqueifier;
// Convert the file_name_prefix to have the same path divider as prj_dir
String_Const_u8 file_name_prefix = push_string_copy(scratch, string_prefix(file_name, prj_dir.size));
for (int j = 0; j < file_name_prefix.size; j++)
{
if (character_is_slash(file_name_prefix.str[j])) file_name_prefix.str[j] = path_divider;
}
// If the full path to the file matches the project path,
// append a project local unique identifier to the filename
// otherwise, simply add on the full path to the file
if (string_match(file_name_prefix, prj_dir))
{
String_Const_u8 file_name_minus_prj_dir = string_skip(file_name, prj_dir.size);
uniqueifier = file_name_minus_prj_dir;
}
else
{
uniqueifier = file_name;
}
String_u8 builder = Su8(conflict->unique_name_in_out,
conflict->unique_name_len_in_out,
conflict->unique_name_capacity);
string_append(&builder, string_u8_litexpr(" <"));
string_append(&builder, uniqueifier);
string_append(&builder, string_u8_litexpr(">"));
conflict->unique_name_len_in_out = builder.size;
}
// double check that each previously conflicting filename is unique
// on a conflict, fall back to the full system path
for (int i = 0; i < conflict_count - 1; i++)
{
String_Const_u8 unique_name_i = SCu8(conflicts[i].unique_name_in_out, conflicts[i].unique_name_len_in_out);
for (int j = i + 1; j < conflict_count; j++)
{
String_Const_u8 unique_name_j = SCu8(conflicts[j].unique_name_in_out, conflicts[j].unique_name_len_in_out);
if (string_match(unique_name_i, unique_name_j))
{
print_message(app, string_u8_litexpr("Unable to provide a unique name for a file. Falling back to its full system path"));
Assert(conflicts[j].file_name.size <= conflicts[j].unique_name_capacity);
block_copy(conflicts[j].unique_name_in_out, conflicts[j].file_name.str, conflicts[j].file_name.size);
}
}
}
}
function void
parse_async__inner(Async_Context *actx, Buffer_ID buffer_id,
String_Const_u8 contents, Token_Array *tokens, i32 limit_factor){
@ -859,8 +742,68 @@ BUFFER_HOOK_SIG(default_begin_buffer){
String_Const_u8 ext = string_file_extension(file_name);
for (i32 i = 0; i < extensions.count; ++i){
if (string_match(ext, extensions.strings[i])){
treat_as_code = true;
break;
if (string_match(ext, string_u8_litexpr("cpp")) ||
string_match(ext, string_u8_litexpr("h")) ||
string_match(ext, string_u8_litexpr("c")) ||
string_match(ext, string_u8_litexpr("hpp")) ||
string_match(ext, string_u8_litexpr("cc"))){
treat_as_code = true;
}
#if 0
treat_as_code = true;
if (string_match(ext, string_u8_litexpr("cs"))){
if (parse_context_language_cs == 0){
init_language_cs(app);
}
parse_context_id = parse_context_language_cs;
}
if (string_match(ext, string_u8_litexpr("java"))){
if (parse_context_language_java == 0){
init_language_java(app);
}
parse_context_id = parse_context_language_java;
}
if (string_match(ext, string_u8_litexpr("rs"))){
if (parse_context_language_rust == 0){
init_language_rust(app);
}
parse_context_id = parse_context_language_rust;
}
if (string_match(ext, string_u8_litexpr("cpp")) ||
string_match(ext, string_u8_litexpr("h")) ||
string_match(ext, string_u8_litexpr("c")) ||
string_match(ext, string_u8_litexpr("hpp")) ||
string_match(ext, string_u8_litexpr("cc"))){
if (parse_context_language_cpp == 0){
init_language_cpp(app);
}
parse_context_id = parse_context_language_cpp;
}
// TODO(NAME): Real GLSL highlighting
if (string_match(ext, string_u8_litexpr("glsl"))){
if (parse_context_language_cpp == 0){
init_language_cpp(app);
}
parse_context_id = parse_context_language_cpp;
}
// TODO(NAME): Real Objective-C highlighting
if (string_match(ext, string_u8_litexpr("m"))){
if (parse_context_language_cpp == 0){
init_language_cpp(app);
}
parse_context_id = parse_context_language_cpp;
}
#endif
break;
}
}
}
@ -882,7 +825,6 @@ BUFFER_HOOK_SIG(default_begin_buffer){
b32 use_lexer = false;
if (treat_as_code){
wrap_lines = def_get_config_b32(vars_save_string_lit("enable_code_wrapping"));
// TODO(PS): @Remove - consider removing the lexer for now? later, replace in favor of tree-sitter
use_lexer = true;
}
@ -984,8 +926,6 @@ BUFFER_HOOK_SIG(default_file_save){
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Line_Ending_Kind *eol = scope_attachment(app, scope, buffer_eol_setting,
Line_Ending_Kind);
clean_all_lines_buffer(app, buffer_id, CleanAllLinesMode_RemoveBlankLines);
switch (*eol){
case LineEndingKind_LF:
{
@ -1108,17 +1048,12 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
make_data_struct(&buffer_id));
}
loco_on_buffer_edit(app, buffer_id, old_range, new_range);
// no meaning for return
return(0);
}
BUFFER_HOOK_SIG(default_end_buffer){
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
loco_on_buffer_end(app, buffer_id);
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
if (lex_task_ptr != 0){
async_task_cancel(app, &global_async_system, *lex_task_ptr);
@ -1154,7 +1089,7 @@ set_all_default_hooks(Application_Links *app){
set_custom_hook_memory_size(app, HookID_DeltaRule,
delta_ctx_size(fixed_time_cubic_delta_memory_size));
set_custom_hook(app, HookID_BufferNameResolver, gs_buffer_name_resolution);
set_custom_hook(app, HookID_BufferNameResolver, default_buffer_name_resolution);
set_custom_hook(app, HookID_BeginBuffer, default_begin_buffer);
set_custom_hook(app, HookID_EndBuffer, end_buffer_close_jump_list);

View File

@ -34,6 +34,7 @@
#include "generated/lexer_cpp.h"
#include "4coder_variables.h"
#include "4coder_audio.h"
#include "4coder_profile.h"
#include "4coder_async_tasks.h"
#include "4coder_string_match.h"
@ -63,7 +64,6 @@
#include "4coder_profile_inspect.h"
#include "4coder_tutorial.h"
#include "4coder_search_list.h"
#include "4coder_modal.h"
////////////////////////////////
@ -139,9 +139,8 @@
#include "4coder_doc_commands.cpp"
#include "4coder_docs.cpp"
#include "4coder_variables.cpp"
#include "4coder_audio.cpp"
#include "4coder_search_list.cpp"
#include "4coder_modal.cpp"
#include "4coder_yeet.cpp"
#include "4coder_examples.cpp"

View File

@ -850,15 +850,21 @@ draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID
i64 cursor_pos = view_get_cursor_pos(app, view_id);
i64 mark_pos = view_get_mark_pos(app, view_id);
if (is_active_view){
Modal_Mode* mode_curr = modal_get_mode_curr();
FColor c0 = mode_curr->cursor_color;
FColor c1 = fcolor_id(defcolor_at_cursor);
draw_character_block(app, text_layout_id, cursor_pos, roundness, c0);
paint_text_color_pos(app, text_layout_id, cursor_pos, c1);
draw_character_wire_frame(app, text_layout_id, mark_pos, roundness, outline_thickness, c0);
} else {
draw_character_wire_frame(app, text_layout_id, mark_pos, roundness, outline_thickness, fcolor_id(defcolor_mark));
draw_character_wire_frame(app, text_layout_id, cursor_pos, roundness, outline_thickness, fcolor_id(defcolor_cursor, cursor_sub_id));
draw_character_block(app, text_layout_id, cursor_pos, roundness,
fcolor_id(defcolor_cursor, cursor_sub_id));
paint_text_color_pos(app, text_layout_id, cursor_pos,
fcolor_id(defcolor_at_cursor));
draw_character_wire_frame(app, text_layout_id, mark_pos,
roundness, outline_thickness,
fcolor_id(defcolor_mark));
}
else{
draw_character_wire_frame(app, text_layout_id, mark_pos,
roundness, outline_thickness,
fcolor_id(defcolor_mark));
draw_character_wire_frame(app, text_layout_id, cursor_pos,
roundness, outline_thickness,
fcolor_id(defcolor_cursor, cursor_sub_id));
}
}
}

View File

@ -208,6 +208,61 @@ CUSTOM_DOC("Example of query_user_string and query_user_number")
}
}
global Audio_Control the_music_control = {};
CUSTOM_COMMAND_SIG(music_start)
CUSTOM_DOC("Starts the music.")
{
local_persist Audio_Clip the_music_clip = {};
if (the_music_clip.sample_count == 0){
Scratch_Block scratch(app);
FILE *file = def_search_normal_fopen(scratch, "audio_test/chtulthu.wav", "rb");
if (file != 0){
the_music_clip = audio_clip_from_wav_FILE(&global_permanent_arena, file);
fclose(file);
}
}
if (!def_audio_is_playing(&the_music_control)){
the_music_control.loop = true;
the_music_control.channel_volume[0] = 1.f;
the_music_control.channel_volume[1] = 1.f;
def_audio_play_clip(the_music_clip, &the_music_control);
}
}
CUSTOM_COMMAND_SIG(music_stop)
CUSTOM_DOC("Stops the music.")
{
def_audio_stop(&the_music_control);
}
CUSTOM_COMMAND_SIG(hit_sfx)
CUSTOM_DOC("Play the hit sound effect")
{
local_persist Audio_Clip the_hit_clip = {};
if (the_hit_clip.sample_count == 0){
Scratch_Block scratch(app);
FILE *file = def_search_normal_fopen(scratch, "audio_test/hit.wav", "rb");
if (file != 0){
the_hit_clip = audio_clip_from_wav_FILE(&global_permanent_arena, file);
fclose(file);
}
}
local_persist u32 index = 0;
local_persist Audio_Control controls[8] = {};
Audio_Control *control = &controls[index%8];
if (!def_audio_is_playing(control)){
control->loop = false;
control->channel_volume[0] = 1.f;
control->channel_volume[1] = 1.f;
def_audio_play_clip(the_hit_clip, control);
index += 1;
}
}
// BOTTOM

View File

@ -55,7 +55,7 @@ parse_buffer_to_jump_array(Application_Links *app, Arena *arena, Buffer_ID buffe
Temp_Memory_Block line_auto_closer(arena);
if (is_valid_line(app, buffer, line)){
String_Const_u8 line_str = push_buffer_line(app, arena, buffer, line);
Parsed_Jump parsed_jump = gs_parse_jump_location(line_str);
Parsed_Jump parsed_jump = parse_jump_location(line_str);
if (parsed_jump.success){
Buffer_ID jump_buffer = {};
if (open_file(app, &jump_buffer, parsed_jump.location.file, false, true)){

View File

@ -59,119 +59,6 @@ check_is_note(String_Const_u8 line, u64 colon_pos){
return(is_note);
}
/* ERROR EXAMPLES
These are the cases that gs_parse_jump_location is designed to parse.
############################# JAVASCRIPT / NODE ERROR ##########################
C:\psjr\blackbird\test.js:2
console.error("Foo);
^^^^^^
SyntaxError: Invalid or unexpected token
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
############################# MSVC ERROR #######################################
test.c(4): error C2632: 'int' followed by 'int' is illegal
############################# CLANG ERROR ######################################
test.c:4:1: error: cannot combine with previous 'int' declaration specifier
int main(int argc, char** args) {
############################# JAI ERROR ########################################
C:/projects/games/atof//src/cards.jai:106,48: Error: Semicolon expected after expression.
}
return card_index, (<< collection)[card_index]
*/
function Parsed_Jump
gs_parse_jump_location(String_Const_u8 line)
{
Parsed_Jump jump = {};
jump.sub_jump_indented = (string_get_character(line, 0) == ' ');
String_Const_u8 reduced_line = string_skip_chop_whitespace(line);
u64 whitespace_length = (u64)(reduced_line.str - line.str);
line = reduced_line;
String_Const_u8 separators = str8_lit(":(),"); // characters used to separate paths, indices, and notes
u64 sep1 = string_find_first_of_set(line, separators);
// on windows, paths might have a colon in them. ie. C:\some\path\file.cpp
// we want to skip this first colon - so check if there's a slash after it
// and skip in that case.
if (sep1 + 1 < line.size)
{
if (character_is_slash(string_get_character(line, sep1 + 1))){
u64 next_sep = string_find_first_of_set(
string_skip(line, sep1 + 1),
separators
);
sep1 = next_sep + sep1 + 1;
}
}
u64 sep2 = string_find_first_of_set(
string_skip(line, sep1 + 1),
separators
) + sep1 + 1;
u64 sep3 = string_find_first_of_set(
string_skip(line, sep2 + 1),
separators
) + sep2 + 1;
// TODO(PS): check_is_note? - seems to be checking for test.c(4): note
// ^^^^
// and setting jump.sub_jump_note = true. Not sure what this is for yet
if (sep1 < line.size) {
String_Const_u8 file_name = string_prefix(line, sep1);
if (file_name.size > 0) {
jump.location.file = file_name;
if (sep2 < line.size) {
String_Const_u8 line_number = string_skip(string_prefix(line, sep2), sep1 + 1);
if (string_is_integer(line_number, 10)) {
jump.location.line = (i32)string_to_integer(line_number, 10);
// NOTE(PS): we must at least get a line number to consider the line
// to contain a valid jump location
jump.success = true;
}
}
// NOTE(PS): columns are optional since MSVC doesn't output them
if (sep3 < line.size) {
String_Const_u8 column_number = string_skip(string_prefix(line, sep3), sep2 + 1);
if (string_is_integer(column_number, 10)) {
jump.location.column = (i32)string_to_integer(column_number, 10);
}
jump.colon_position = (i32)(sep3 + whitespace_length);
}
}
}
if (!jump.success){
block_zero_struct(&jump);
}
else{
jump.is_sub_jump = (jump.sub_jump_indented || jump.sub_jump_note);
}
return(jump);
}
function Parsed_Jump
parse_jump_location(String_Const_u8 line){
Parsed_Jump jump = {};
@ -246,10 +133,6 @@ parse_jump_location(String_Const_u8 line){
}
u64 colon_pos2 = string_find_first(string_skip(line, colon_pos1 + 1), ':') + colon_pos1 + 1;
u64 comma_pos2 = string_find_first(string_skip(line, colon_pos1 + 1), ',') + colon_pos1 + 1;
if (comma_pos2 < colon_pos2) {
colon_pos2 = comma_pos2;
}
u64 colon_pos3 = string_find_first(string_skip(line, colon_pos2 + 1), ':') + colon_pos2 + 1;
if (colon_pos3 < line.size){

View File

@ -274,7 +274,12 @@ lister__backspace_text_field__file_path(Application_Links *app){
User_Input input = get_current_input(app);
String_Const_u8 text_field = lister->text_field.string;
String_Const_u8 new_hot = string_remove_last_folder(text_field);
lister->text_field.size = new_hot.size;
b32 is_modified = has_modifier(&input, KeyCode_Control);
b32 whole_word_when_mod = def_get_config_b32(vars_save_string_lit("lister_whole_word_backspace_when_modified"));
b32 whole_word_backspace = (is_modified == whole_word_when_mod);
if (whole_word_backspace){
lister->text_field.size = new_hot.size;
}
set_hot_directory(app, new_hot);
// TODO(allen): We have to protect against lister_call_refresh_handler
// changing the text_field here. Clean this up.

View File

@ -1,105 +0,0 @@
function void
modal_init(u32 mode_cap, Thread_Context* tctx){
Assert(mode_cap > 0);
modal_modes_cap = mode_cap;
modal_modes = base_array(tctx->allocator, Modal_Mode, mode_cap);
modal_map_id_global = vars_save_string_lit("keys_global");
modal_map_id_file = vars_save_string_lit("keys_file");
modal_map_id_code = vars_save_string_lit("keys_code");
for (u32 i = 0; i < modal_modes_cap; i++){
Modal_Mode* mode = modal_modes + i;
mapping_init(tctx, &mode->map);
setup_essential_mapping(&mode->map, modal_map_id_global, modal_map_id_file, modal_map_id_code);
}
}
function Modal_Mode*
modal_get_mode(u32 mode_id)
{
if (mode_id >= modal_modes_cap) return 0;
return modal_modes + mode_id;
}
function void
modal_bind(Mapping* mode, Command_Map* map, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
{
map_set_binding_l(mode, map, BindFWrap_(proc), InputEventKind_KeyStroke, key_code, mod_key_code0, mod_key_code1, 0);
}
function void
modal_bind(u32 mode_id, String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
{
Assert(mode_id < modal_modes_cap);
Modal_Mode* mode = modal_get_mode(mode_id);
Mapping* m = &mode->map;
Command_Map* map = mapping_get_or_make_map(m, map_id);
modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1);
}
function void
modal_bind_all(String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
{
for (u32 i = 0; i < modal_modes_cap; i++)
{
Mapping* m = &modal_modes[i].map;
Command_Map* map = mapping_get_or_make_map(m, map_id);
modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1);
}
}
function Modal_Mode*
modal_get_mode_curr()
{
return modal_get_mode(modal_curr_mode);
}
function void
modal_set_mode(u32 mode_id)
{
modal_last_mode = modal_curr_mode;
modal_curr_mode = mode_id;
}
function u32
modal_get_next_mode(u32 base)
{
u32 result = (base + 1) % modal_modes_cap;
return result;
}
function void
modal_set_cursor_color(u32 mode_id, FColor color)
{
Modal_Mode* mode = modal_get_mode(mode_id);
mode->cursor_color = color;
}
function void
modal_set_cursor_color_u32(u32 mode_id, u32 color)
{
FColor fc = {};
fc.argb = color;
modal_set_cursor_color(mode_id, fc);
}
CUSTOM_COMMAND_SIG(modal_set_mode_toggle)
{
u32 next_mode = modal_last_mode;
if (next_mode == modal_curr_mode)
{
next_mode = modal_get_next_mode(next_mode);
}
modal_set_mode(next_mode);
}
CUSTOM_COMMAND_SIG(modal_set_mode_next)
{
u32 next_mode = modal_get_next_mode(modal_curr_mode);
modal_set_mode(next_mode);
}

View File

@ -1,17 +0,0 @@
/* date = February 10th 2024 3:00 pm */
#ifndef FRED_MODAL_H
#define FRED_MODAL_H
struct Modal_Mode
{
Mapping map;
FColor cursor_color;
String_Const_u8 name;
};
typedef CUSTOM_COMMAND_SIG(custom_cmd);
function Modal_Mode* modal_get_mode_curr();
#endif //FRED_MODAL_H

View File

@ -459,23 +459,17 @@ prj_generate_project(Arena *scratch, String8 script_path, String8 script_file, S
String8 file_name = push_u8_stringf(scratch, "%.*s/project.4coder", string_expand(script_path));
String8 treat_as_code = def_get_config_string(scratch, vars_save_string_lit("treat_as_code"));
String8Array extensions = parse_extension_line_to_extension_list(scratch, treat_as_code);
FILE *out = fopen((char*)file_name.str, "wb");
if (out != 0){
fprintf(out, "version(2);\n");
fprintf(out, "project_name = \"%.*s\";\n", string_expand(binary_file));
fprintf(out, "patterns = {\n");
for (i32 i = 0; i < extensions.count; i++) {
fprintf(out, "\"*.%.*s\",\n", string_expand(extensions.strings[i]));
}
// fprintf(out, "\"*.c\",\n");
// fprintf(out, "\"*.cpp\",\n");
// fprintf(out, "\"*.h\",\n");
// fprintf(out, "\"*.m\",\n");
// fprintf(out, "\"*.bat\",\n");
// fprintf(out, "\"*.sh\",\n");
fprintf(out, "\"*.c\",\n");
fprintf(out, "\"*.cpp\",\n");
fprintf(out, "\"*.h\",\n");
fprintf(out, "\"*.m\",\n");
fprintf(out, "\"*.bat\",\n");
fprintf(out, "\"*.sh\",\n");
fprintf(out, "\"*.4coder\",\n");
fprintf(out, "};\n");
fprintf(out, "blacklist_patterns = {\n");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -38,10 +38,6 @@ defcolor_back_cycle = managed_id_declare(app, string_u8_litexpr("colors"), strin
defcolor_text_cycle = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_text_cycle"));
defcolor_line_numbers_back = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_back"));
defcolor_line_numbers_text = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_text"));
defcolor_function = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_function"));
defcolor_operator = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_operator"));
defcolor_type = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_type"));
defcolor_macro = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_macro"));
view_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_rewrite_loc"));
view_next_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_next_rewrite_loc"));
view_paste_index_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_paste_index_loc"));
@ -60,6 +56,4 @@ buffer_lex_task = managed_id_declare(app, string_u8_litexpr("attachment"), strin
buffer_wrap_lines = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_wrap_lines"));
sticky_jump_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("sticky_jump_marker_handle"));
attachment_tokens = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("attachment_tokens"));
loco_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("loco_marker_handle"));
loco_marker_pair_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("loco_marker_pair_handle"));
}

View File

@ -348,7 +348,7 @@ os_popup_error(char *title, char *message){
#if defined(FRED_INTERNAL)
function inline void
mac_profile(char *name, u64 begin, u64 end){
//printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
}
#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\
@ -909,7 +909,7 @@ mac_toggle_fullscreen(void){
mac_profile("Frame", prev_timer_start, mac_vars.timer_start);
#if FRED_INTERNAL
//printf("\n");
printf("\n");
#endif
}
@ -946,7 +946,7 @@ mac_toggle_fullscreen(void){
- (void)keyDown:(NSEvent*)event{
// NOTE(yuval): Process keyboard event
[self process_keyboard_event:event down:true];
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
// TODO(allen): Deduplicate with insertText version
// NOTE(allen): We need to manually send text for '\n' and '\t'
@ -961,9 +961,9 @@ mac_toggle_fullscreen(void){
}
if ((c == '\t') || (c == '\n')){
u8 *str = push_array(&mac_vars.frame_arena, u8, 1);
str[0] = (u8)c;
str[0] = (u8)c;
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
event->kind = InputEventKind_TextInsert;
event->text.string = SCu8(str, 1);
event->text.next_text = 0;
@ -1206,17 +1206,11 @@ mac_toggle_fullscreen(void){
system_signal_step(0);
}
} else {
} else{
mac_vars.active_key_stroke = 0;
mac_vars.active_text_input = 0;
if (key != 0){
// NOTE(PS): when releasing the command key, assume all keys being pressed
// are released
if (key == KeyCode_Command) {
mods->count = 0;
}
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
event->kind = InputEventKind_KeyRelease;
event->key.code = key;

View File

@ -16,7 +16,7 @@ struct Mac_Metal{
function
mac_render_sig(mac_metal__render){
#if defined(FRED_INTERNAL)
//printf("Redering using Metal!\n");
printf("Redering using Metal!\n");
#endif
Mac_Metal *metal = (Mac_Metal*)renderer;

View File

@ -1697,6 +1697,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
log_os("Initializing thread context...\n");
// NOTE(allen): This thing
InitializeCriticalSection(&memory_tracker_mutex);
// NOTE(allen): context setup

View File

@ -20,10 +20,10 @@ use_scope_highlight = true;
use_paren_helper = true;
use_comment_keywords = true;
lister_whole_word_backspace_when_modified = true;
show_line_number_margins = true;
show_line_number_margins = false;
enable_output_wrapping = false;
enable_undo_fade_out = false;
enable_undo_fade_out = true;
// cursor_roundess is a value [0,50] setting the radius of
// the cursor and mark's roundness as a percentage of their width
@ -40,14 +40,14 @@ mark_thickness = 2;
lister_roundness = 20;
// Code Wrapping
treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm.js.ts.tsx.css.html.jai.json.mm.metal.glsl.hlsl";
enable_virtual_whitespace = false;
virtual_whitespace_regular_indent = 2;
enable_code_wrapping = false;
treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm";
enable_virtual_whitespace = true;
virtual_whitespace_regular_indent = 4;
enable_code_wrapping = true;
// This only applies to code files in code-wrapping mode.
// Plain text and code files without virtual-whitespace will not be effected.
automatically_indent_text_on_save = false;
automatically_indent_text_on_save = true;
// When set to true, all unsaved changes will be saved on a build.
automatically_save_changes_on_build = true;
@ -57,16 +57,16 @@ automatically_load_project = false;
// Indentation
indent_with_tabs = false;
indent_width = 2;
default_tab_width = 2;
indent_width = 4;
default_tab_width = 4;
// Theme
default_theme_name = "theme-gs";
default_theme_name = "4coder";
// Font
default_font_name = "liberation-mono.ttf";
default_font_size = 14;
default_font_hinting = true;
default_font_size = 16;
default_font_hinting = false;
// aa modes:
// 8bit - mono-chrome 0-255 opacity channel per pixel
@ -74,7 +74,7 @@ default_font_hinting = true;
default_font_aa_mode = "8bit";
// User
user_name = "PS";
user_name = "not-set";
// Keyboard AltGr setting
lalt_lctrl_is_altgr = false;

View File

@ -1,69 +0,0 @@
defcolor_bar = 0xFF1e1e1e;
defcolor_base = 0xFFfcaa05;
defcolor_pop1 = 0xffde8150;
defcolor_pop2 = 0xFFFF0000;
defcolor_back = 0xFF1e1e1e;
defcolor_margin = 0xFF222425;
defcolor_margin_hover = 0xff63523d;
defcolor_margin_active = 0xff63523d;
defcolor_list_item = { 0xFF222425, defcolor_back};
defcolor_list_item_hover = { 0xff362e25, defcolor_margin};
defcolor_list_item_active = { 0xff63523d, defcolor_margin};
defcolor_cursor = { 0xFF00EE00, 0xffe0741b, 0xff1be094, 0xffba60c4 };
defcolor_at_cursor = 0xFF0C0C0C;
defcolor_highlight_cursor_line = 0xFF1E1E1E;
defcolor_highlight = 0xFF303040;
defcolor_at_highlight = 0xFFFF44DD;
defcolor_mark = 0xFF494949;
defcolor_text_default = 0xffd4d4d4;
defcolor_comment = 0xff6a9956;
defcolor_comment_pop = { 0xff2ab34f, 0xFFdb2828 };
defcolor_keyword = 0xffc586c0;
defcolor_str_constant = 0xffa77864;
defcolor_char_constant = 0xffa77864;
defcolor_int_constant = 0xffb4cda7;
defcolor_float_constant = 0xffb4cda7;
defcolor_bool_constant = 0xffb4cda7;
defcolor_preproc = 0xFFc485bf;
defcolor_include = 0xffc485bf;
defcolor_special_character = 0xFFFF0000;
defcolor_ghost_character = 0xFF4E5E46;
defcolor_highlight_junk = 0xFF3A0000;
defcolor_highlight_white = 0xFF003A3A;
defcolor_paste = 0xFFDDEE00;
defcolor_undo = 0xFF00DDEE;
defcolor_back_cycle = { 0xff282828, 0xff323232, 0xff3C3C3C, defcolor_back, };
defcolor_text_cycle = { 0xFFA00000, 0xFF00A000, 0xFF0030B0, 0xFFA0A000 };
defcolor_line_numbers_back = defcolor_back;
defcolor_line_numbers_text = 0xFF404040;
fleury_color_syntax_crap = 0xff5c4d3c;
fleury_color_operators = 0xFFbd2d2d;
fleury_color_inactive_pane_overlay = 0x44000000;
fleury_color_inactive_pane_background = 0xff1e1e1e;
fleury_color_file_progress_bar = 0x60634323;
fleury_color_brace_highlight = { 0xff8ffff2 };
fleury_color_brace_line = { 0x809ba290 };
fleury_color_brace_annotation = { 0x809ba290 };
fleury_color_index_product_type = 0xFFedb211;
fleury_color_index_sum_type = 0xFFa7eb13;
fleury_color_index_function = 0xFFde451f;
fleury_color_index_macro = 0xFF2895c7;
fleury_color_index_constant = 0xff6eb535;
fleury_color_index_comment_tag = 0xffffae00;
fleury_color_index_decl = 0xffc9598a;
fleury_color_cursor_macro = 0xffde2368;
fleury_color_cursor_power_mode = 0xffefaf2f;
fleury_color_cursor_inactive = 0xFF880000;
fleury_color_plot_cycle = { 0xff03d3fc, 0xff22b80b, 0xfff0bb0c, 0xfff0500c };
fleury_color_token_highlight = 0x88f2d357;
fleury_color_token_minor_highlight = 0x44d19045;
fleury_color_error_annotation = 0xffff0000;
fleury_color_lego_grab = 0xffefaf6f;
fleury_color_lego_splat = 0xffefaaef;
fleury_color_comment_user_name = 0xffffdd23;
defcolor_function = 0xffdadaa9;
defcolor_operator = 0xffc5c5c5;
defcolor_type = 0xff4dc5ac;
defcolor_macro = 0xff5190c5;

View File

@ -1,37 +0,0 @@
version(2);
project_name = "4ed.exe";
patterns = {
"*.c",
"*.cpp",
"*.h",
"*.m",
"*.bat",
"*.sh",
"*.4coder",
};
blacklist_patterns = {
".*",
};
load_paths_base = {
{ ".", .relative = true, .recursive = true, },
};
load_paths = {
.win = load_paths_base,
.linux = load_paths_base,
.mac = load_paths_base,
};
commands = {
.build = { .out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
.win = "code\\bin\\build.bat",
.linux = "./code/bin/package.sh",
.mac = "./code/bin/package-mac.sh", },
.run = { .out = "*run*", .footer_panel = false, .save_dirty_files = false,
.win = "build\\4ed.exe",
.linux = "build/4ed",
.mac = "build/4ed", },
};
fkey_command = {
.F1 = "build",
.F2 = "run",
};