@@ -1516,6 +1516,183 @@ CUSTOM_DOC("Performs VS-style uncommenting on the selected range.")
1516
1516
no_mark_snap_to_cursor (app, view);
1517
1517
}
1518
1518
1519
+ struct F4_LOCInfo
1520
+ {
1521
+ F4_LOCInfo *next;
1522
+ String_Const_u8 name;
1523
+ i64 lines;
1524
+ i64 whitespace_only_lines;
1525
+ i64 open_brace_only_lines;
1526
+ };
1527
+
1528
+ function F4_LOCInfo *
1529
+ F4_LOCInfoFromBuffer (Application_Links *app, Arena *arena, Buffer_ID buffer)
1530
+ {
1531
+ F4_LOCInfo *first = 0 ;
1532
+ F4_LOCInfo *last = 0 ;
1533
+
1534
+ F4_LOCInfo *file_info = push_array_zero (arena, F4_LOCInfo, 1 );
1535
+ sll_queue_push (first, last, file_info);
1536
+ file_info->name = str8_lit (" all" );
1537
+ F4_LOCInfo *active_info = 0 ;
1538
+
1539
+ i64 line_count = buffer_get_line_count (app, buffer);
1540
+ for (i64 line_idx = 0 ; line_idx < line_count; line_idx += 1 )
1541
+ {
1542
+ Scratch_Block scratch (app, arena);
1543
+ String_Const_u8 line = push_buffer_line (app, scratch, buffer, line_idx);
1544
+ if (line.size != 0 && line.str [line.size -1 ] == ' \r ' )
1545
+ {
1546
+ line.size -= 1 ;
1547
+ }
1548
+
1549
+ // - rjf: begin a section if we find a root divider comment here
1550
+ if (line.size >= 3 && line.str [0 ] == ' /' && line.str [1 ] == ' /' && line.str [2 ] == ' ~' )
1551
+ {
1552
+ active_info = push_array_zero (arena, F4_LOCInfo, 1 );
1553
+ active_info->name = push_string_copy (arena, string_substring (line, Ii64 (3 , line.size )));
1554
+ sll_queue_push (first, last, active_info);
1555
+ }
1556
+
1557
+ // - rjf: find out if this is a line with only whitespace
1558
+ b32 is_only_whitespace = true ;
1559
+ {
1560
+ for (u64 i = 0 ; i < line.size ; i += 1 )
1561
+ {
1562
+ if (!character_is_whitespace (line.str [i]))
1563
+ {
1564
+ is_only_whitespace = false ;
1565
+ break ;
1566
+ }
1567
+ }
1568
+ }
1569
+
1570
+ // - rjf: find out if this is a line with only whitespace and an open brace
1571
+ b32 is_only_open_brace = false ;
1572
+ if (is_only_whitespace == false )
1573
+ {
1574
+ for (u64 i = 0 ; i < line.size ; i += 1 )
1575
+ {
1576
+ if (!character_is_whitespace (line.str [i]))
1577
+ {
1578
+ is_only_open_brace = line.str [i] == ' {' ;
1579
+ if (!is_only_open_brace)
1580
+ {
1581
+ break ;
1582
+ }
1583
+ }
1584
+ }
1585
+ }
1586
+
1587
+ // - rjf: increment line counts
1588
+ {
1589
+ file_info->lines += 1 ;
1590
+ if (active_info != 0 )
1591
+ {
1592
+ active_info->lines += 1 ;
1593
+ }
1594
+ if (is_only_whitespace)
1595
+ {
1596
+ file_info->whitespace_only_lines += 1 ;
1597
+ if (active_info != 0 )
1598
+ {
1599
+ active_info->whitespace_only_lines += 1 ;
1600
+ }
1601
+ }
1602
+ if (is_only_open_brace)
1603
+ {
1604
+ file_info->open_brace_only_lines += 1 ;
1605
+ if (active_info != 0 )
1606
+ {
1607
+ active_info->open_brace_only_lines += 1 ;
1608
+ }
1609
+ }
1610
+ }
1611
+ }
1612
+
1613
+ return first;
1614
+ }
1615
+
1616
+ function int
1617
+ F4_LOCInfoCompare (const void *a_void_fuck_cplusplus, const void *b_void_fuck_cplusplus)
1618
+ {
1619
+ F4_LOCInfo *a = (F4_LOCInfo *)a_void_fuck_cplusplus;
1620
+ F4_LOCInfo *b = (F4_LOCInfo *)b_void_fuck_cplusplus;
1621
+ return ((a->lines < b->lines ) ? +1 :
1622
+ (a->lines > b->lines ) ? -1 :
1623
+ 0 );
1624
+ }
1625
+
1626
+ CUSTOM_COMMAND_SIG (f4_loc)
1627
+ CUSTOM_DOC(" Counts the lines of code in the current buffer, breaks it down by section, and outputs to the *loc* buffer." )
1628
+ {
1629
+ Scratch_Block scratch (app);
1630
+ View_ID view = get_active_view (app, Access_Read);
1631
+ Buffer_ID buffer = view_get_buffer (app, view, Access_Read);
1632
+
1633
+ // - rjf: get all sections and counts from buffer
1634
+ F4_LOCInfo *infos_list = F4_LOCInfoFromBuffer (app, scratch, buffer);
1635
+
1636
+ // - rjf: build unsorted info in array form
1637
+ int info_count = 0 ;
1638
+ F4_LOCInfo *info_array = 0 ;
1639
+ {
1640
+ for (F4_LOCInfo *info = infos_list; info; info = info->next , info_count += 1 );
1641
+ info_array = push_array_zero (scratch, F4_LOCInfo, info_count);
1642
+ int i = 0 ;
1643
+ for (F4_LOCInfo *info = infos_list; info; info = info->next , i += 1 )
1644
+ {
1645
+ info_array[i] = *info;
1646
+ }
1647
+ }
1648
+
1649
+ // - rjf: sort array
1650
+ {
1651
+ qsort (info_array, info_count, sizeof (F4_LOCInfo), F4_LOCInfoCompare);
1652
+ }
1653
+
1654
+ // - rjf: print loc info
1655
+ Buffer_ID loc_buffer = get_buffer_by_name (app, str8_lit (" *loc*" ), AccessFlag_Write);
1656
+ if (loc_buffer != 0 )
1657
+ {
1658
+ clear_buffer (app, loc_buffer);
1659
+
1660
+ for (int i = 0 ; i < info_count; i += 1 )
1661
+ {
1662
+ F4_LOCInfo *info = info_array + i;
1663
+
1664
+ Scratch_Block scratch2 (app, scratch);
1665
+ int padding = 25 ;
1666
+ int chrs = (int )info->name .size ;
1667
+ int spaces = 0 ;
1668
+ if (chrs > padding)
1669
+ {
1670
+ chrs = padding;
1671
+ spaces = 0 ;
1672
+ }
1673
+ else
1674
+ {
1675
+ spaces = padding - chrs;
1676
+ }
1677
+
1678
+ if (spaces < 0 )
1679
+ {
1680
+ spaces = 0 ;
1681
+ }
1682
+
1683
+ String_Const_u8 string = push_stringf (scratch2,
1684
+ " >>> %.*s%.*s: %6i lines; %6i whitespace; %6i open braces; %6i significant\n " ,
1685
+ chrs, info->name .str ,
1686
+ spaces, " " ,
1687
+ (int )info->lines ,
1688
+ (int )info->whitespace_only_lines ,
1689
+ (int )info->open_brace_only_lines ,
1690
+ (int )(info->lines - (info->whitespace_only_lines +info->open_brace_only_lines )));
1691
+ b32 write_successful = buffer_replace_range (app, loc_buffer, Ii64 (buffer_get_size (app, loc_buffer)), string);
1692
+ write_successful = write_successful;
1693
+ }
1694
+ }
1695
+ }
1519
1696
1520
1697
// ~ NOTE(rjf): Deprecated names:
1521
1698
CUSTOM_COMMAND_SIG (fleury_write_text_input)
0 commit comments