4coder » Forums » Bugs in the Customization API
teryror
Tristan Dannenberg
4 posts

Simultaneously a dreamer and an early quitter

#12723 Bugs in the Customization API
1 month, 3 weeks ago Edited by Tristan Dannenberg on Aug. 3, 2017, 7:37 a.m.

Hi Allen,

I've been working on some rather involved customizations, essentially replacements for special emacs modes I used to use (or would have, had I invested some more time into learning them). I've come across some bugs in the 4coder API, as well as some (simple?) things that would make my time with this a whole lot easier.

  • Opening more than 8 Query_Bars at once crashes 4coder:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    CUSTOM_COMMAND_SIG(repro_query_bar_crash) {
        Query_Bar qb = {0};
        qb.prompt = make_lit_string("Prompt: ");
        qb.string = make_lit_string("Some text...");
        
        for (int i = 0; i < 9; ++i) {
            start_query_bar(app, &qb, 0);
        }
        
        // We won't even make it here
    }
      
    

    I assume this is because they were not intended to be used the way I did. I built my own fuzzy string matcher, and essentially tried to replace the interactive_open UI by opening and closing these as the user types. Limiting the number of files shown to 7 (leaving the 8th bar for input) solved the problem.
    This turned out to work so well that I used the same infrastructure to build other fuzzy lists, e.g. for selecting an arbitrary command to execute. What I really would have liked is to just have some function that displays the UI, but uses the string matcher and list of strings I provide.
  • directory_cd doesn't do anything unless rel_path is "..". I can't really provide repro code here, because the command is supposed to fail if the specified relative path does not exist, and I don't know the directory contents you will be testing with.
    (Edit: It just occured to me that this one is almost certainly platform dependent. All of this is on Windows 8.1)
  • This is the one that surprised me the most: using buffer_set_setting to set BufferSetting_MapID exhibits really strange behaviour: if the specified mapid is anything other than 0, mapid_global (0x01000000), or mapid_file (0x01000001), the call silently fails and the buffer's mapid will be set to mapid_file instead.
    Speaking of buffer settings, I would also really like to associate some arbitrary information with a buffer that can be retrieved later. For example, when opening a buffer in *hex* mode, I create a new buffer where the actual byte values will be pretty printed. Many commands interacting with the hex buffer need to also reference the source buffer (i.e. the one viewed through the hex buffer). This relation could be expressed by storing the source buffer's buffer_id with the hex buffer.
I know you have a lot on your plate; the feature requests here are mere suggestions, of course.

I'm still in the process of upgrading my customization code to the newest 4coder version (which I've been meaning to do for nearly half a year now!), and heavily improving on my old implementation of these bigger features. That's why I won't share the actual customization code yet - most of it isn't done yet.
That's just a matter of time, though. Hacking on 4coder has been my go-to programming activity ourside of work for the past week or so, and it is tremendous fun.

Thanks again for making such a fantastic tool!
Cheers
Mr4thDimention
Allen Webster
266 posts
2 projects

Heyo

#12766 Bugs in the Customization API
1 month, 2 weeks ago

I'm glad you are at least having fun with it!

These are all pretty interesting issues you've brought up, so I'll break them down and address them one at a time.

1. Query Bars are intentionally limited to 8 per view because they were never meant as the long term GUI solution, but just a hack that unfortunately stayed in the code for too long. The idea of a more general GUI system, where you can specify a list of strings such as in the file list, as well as many other GUIs you might want, is a big part of what I have been thinking about behind the scenes. These problems will start getting solved in 4.1.0 and later builds.

2. This directory_cd thing is a bit surprising. I will dig into it a bit. A few things that might be going wrong are not using a full path for dir, or not using backslashes.

3. Hmm. I'm not sure what could be going wrong with the mapid. The default customization uses a custom command map for code files and that works, so I would need a repro case for this one.

As far as extra custom variables set on a buffer, that is a really good point. The sticky jump code had the same problem and I just implemented a hash table to map buffer ids to extra memory, but I don't want to force everyone else to write hash tables too... I'll have to think about the right way to solve that one for a bit.
teryror
Tristan Dannenberg
4 posts

Simultaneously a dreamer and an early quitter

#12789 Bugs in the Customization API
1 month, 2 weeks ago Edited by Tristan Dannenberg on Aug. 5, 2017, 4:14 p.m.

I sort of expected you would want a repro case for that, but it really is as simple as it sounds. I too did think I was misusing the API somehow, but after stepping through the assembly for a bit, it seems that you loop over the list of all maps to verify that the specified mapid has been initialized, but somehow end up defaulting to mapid_file anyway?

I'm not sure, I suck at reading x86 assembly, and didn't want to step on your toes by reverse engineering too much.

Here is a full config that creates two command maps, with ID 0 and 1 respectively, and sets the *scratch* buffer to use mapid 0.

You can press the spacebar to run a command that should essentially just trigger an assert that a buffer_set_setting call did what it was supposed to do. You can also comment out said assert to verify that the map has not been set at all, and it's not just the local Buffer_Summary that's not getting updated. (The commands are bound properly, as far as I can tell by using inherit_map, though I don't show that here)

But maybe I AM misusing the API in some way and just going insane?

---

As for directory_cd, here is some code that is roughly equivalent to what I do already (which should work, if I read the documentation right):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
CUSTOM_COMMAND_SIG(repro_cd) {
    char hot_dir_space[1024];
    String hot_dir = make_fixed_width_string(hot_dir_space);
    hot_dir.size = directory_get_hot(app, hot_dir.str, hot_dir.memory_size);
    
    File_List hot_files = get_file_list(app, expand_str(hot_dir));
    for (uint32_t i = 0; i < hot_files.count; ++i) {
        if (hot_files.infos[i].folder) {
            int32_t old_size = hot_dir.size;
            
            directory_cd(app, hot_dir.str, &hot_dir.size, hot_dir.memory_size, hot_files.infos[i].filename, hot_files.infos[i].filename_len);
            
            // This should crash also
            Assert(old_size != hot_dir.size);
            
            break;
        }
    }
}


(I do some more error checking in my own code, but as I said, it fails silently, for me anyways)

With that, thank you for all your efforts!
Mr4thDimention
Allen Webster
266 posts
2 projects

Heyo

#12791 Bugs in the Customization API
1 month, 2 weeks ago

Okay I think this will work perfectly, I'll get these on my bug list and get back to you when I can.