Skip to content

Commit 8654dc5

Browse files
Add directory-level configuration support and debugging (#2)
* feat: add configuration system integration and debugging support * feat: enhance configuration loading with directory-specific support * feat: add directory-level configuration support in README * feat: add changelog for version 0.0.4 with directory-level configuration and fixes * feat: add configuration header and functions for managing settings
1 parent a09e6dc commit 8654dc5

File tree

13 files changed

+1475
-7
lines changed

13 files changed

+1475
-7
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
*.o
22
build/
33
*.test
4-
*.dSYM/
5-
nutshell
4+
*.dSYM/

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
All notable changes to Nutshell will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.0.4] - 2025-03-11
9+
10+
### Added
11+
- Directory-level configuration with `.nutshell.json` files
12+
- Configuration hierarchy: directory configs override user configs which override system configs
13+
- Automatic config reloading when changing directories with `cd`
14+
- Project-specific aliases and settings through directory configs
15+
- Support for different themes per project
16+
17+
### Fixed
18+
- Memory leak in directory path traversal
19+
- Config loading order to properly respect precedence rules

Makefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ TEST_SRC = $(wildcard tests/*.c)
4040
TEST_OBJ = $(TEST_SRC:.c=.o)
4141
TEST_BINS = $(TEST_SRC:.c=.test)
4242

43-
.PHONY: all clean install install-user test test-pkg test-theme test-ai release uninstall uninstall-user
43+
.PHONY: all clean install install-user test test-pkg test-theme test-ai test-config test-dirconfig release uninstall uninstall-user
4444

4545
all: nutshell
4646

@@ -116,6 +116,16 @@ test-ai: tests/test_ai_integration.test tests/test_openai_commands.test tests/te
116116
@./tests/test_ai_shell_integration.test
117117
@echo "All AI tests completed!"
118118

119+
# Add a new target for config tests
120+
test-config: tests/test_config.test
121+
@echo "Running configuration system tests..."
122+
@./tests/test_config.test
123+
124+
# Add a target for directory config tests
125+
test-dirconfig: tests/test_directory_config.test
126+
@echo "Running directory config tests..."
127+
@./tests/test_directory_config.test
128+
119129
# Update the test build rule to exclude main.o
120130
tests/%.test: tests/%.o $(filter-out src/core/main.o, $(OBJ))
121131
$(CC) -o $@ $^ $(LDFLAGS)

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,40 @@ This will switch to the "minimal" theme.
222222

223223
3. Switch to your theme with `theme mytheme`
224224

225+
## Directory-level Configuration
226+
227+
Nutshell now supports project-specific configurations through directory-level config files:
228+
229+
### How it works
230+
231+
- Nutshell searches for a `.nutshell.json` configuration file in the current directory
232+
- If not found, it looks in parent directories until reaching your home directory
233+
- Directory configs take precedence over user configs which take precedence over system configs
234+
- Configurations are automatically reloaded when you change directories using `cd`
235+
236+
### Creating a directory config
237+
238+
Create a `.nutshell.json` file in your project directory:
239+
240+
```json
241+
{
242+
"theme": "minimal",
243+
"aliases": {
244+
"build": "make all",
245+
"test": "make test",
246+
"deploy": "scripts/deploy.sh"
247+
},
248+
"packages": ["gitify"]
249+
}
250+
```
251+
252+
### Benefits
253+
254+
- Project-specific aliases and settings
255+
- Different themes for different projects
256+
- Shared configurations for team projects (add `.nutshell.json` to version control)
257+
- Hierarchical configuration (team settings in parent dir, personal tweaks in subdirs)
258+
225259
## Debugging
226260

227261
For development or troubleshooting, run the debug script:

include/nutshell/config.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef NUTSHELL_CONFIG_H
2+
#define NUTSHELL_CONFIG_H
3+
4+
#include <stdbool.h>
5+
6+
// Configuration structure to store settings
7+
typedef struct {
8+
char *theme; // Current theme name
9+
char **enabled_packages; // Array of enabled package names
10+
int package_count; // Number of enabled packages
11+
char **aliases; // Array of custom aliases
12+
char **alias_commands; // Array of commands for each alias
13+
int alias_count; // Number of aliases
14+
char **scripts; // Array of custom script paths
15+
int script_count; // Number of custom scripts
16+
} Config;
17+
18+
// Global configuration
19+
extern Config *global_config;
20+
21+
// Configuration functions
22+
void init_config_system();
23+
void cleanup_config_system();
24+
25+
// Load configuration from files (checks dir, user, system in that order)
26+
bool load_config_files(); // Renamed from load_config to avoid conflict
27+
28+
// Save current configuration to user config file
29+
bool save_config();
30+
31+
// Update specific configuration settings
32+
bool set_config_theme(const char *theme_name);
33+
bool add_config_package(const char *package_name);
34+
bool remove_config_package(const char *package_name);
35+
bool add_config_alias(const char *alias_name, const char *command);
36+
bool remove_config_alias(const char *alias_name);
37+
bool add_config_script(const char *script_path);
38+
bool remove_config_script(const char *script_path);
39+
40+
// New functions for directory-level configuration
41+
bool reload_directory_config();
42+
void cleanup_config_values();
43+
44+
// Get configuration settings
45+
const char *get_config_theme();
46+
bool is_package_enabled(const char *package_name);
47+
const char *get_alias_command(const char *alias_name);
48+
49+
#endif // NUTSHELL_CONFIG_H

scripts/debug_config.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
# Set debug environment variables
4+
export NUT_DEBUG=1
5+
export NUT_DEBUG_CONFIG=1
6+
7+
# Run the configuration test with debugging
8+
make test-config
9+
10+
# Or run the shell with debugging
11+
# make && ./nutshell

src/core/executor.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <nutshell/core.h>
55
#include <nutshell/utils.h>
6+
#include <nutshell/config.h> // Add this include for reload_directory_config
67
#include <sys/wait.h>
78
#include <fcntl.h>
89
#include <errno.h>
@@ -71,7 +72,12 @@ void execute_command(ParsedCommand *cmd) {
7172

7273
// Handle builtin commands without forking
7374
if (strcmp(cmd->args[0], "cd") == 0) {
74-
if (cmd->args[1]) chdir(cmd->args[1]);
75+
if (cmd->args[1]) {
76+
if (chdir(cmd->args[1]) == 0) {
77+
// Successfully changed directory, reload directory-specific config
78+
reload_directory_config();
79+
}
80+
}
7581
return;
7682
}
7783

src/core/shell.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <nutshell/utils.h>
55
#include <nutshell/theme.h>
66
#include <nutshell/ai.h> // Add this include to access AI functions
7+
#include <nutshell/config.h>
78
#include <readline/readline.h>
89
#include <readline/history.h>
910
#include <string.h>
@@ -59,9 +60,38 @@ void shell_loop() {
5960
char *input;
6061
struct sigaction sa;
6162

63+
// Initialize the configuration system first
64+
if (getenv("NUT_DEBUG")) {
65+
DEBUG_LOG("Initializing configuration system");
66+
}
67+
init_config_system();
68+
6269
// Initialize the theme system
70+
if (getenv("NUT_DEBUG")) {
71+
DEBUG_LOG("Initializing theme system");
72+
}
6373
init_theme_system();
6474

75+
// Load saved theme from config if available
76+
const char *saved_theme = get_config_theme();
77+
if (saved_theme && current_theme && strcmp(current_theme->name, saved_theme) != 0) {
78+
if (getenv("NUT_DEBUG")) {
79+
DEBUG_LOG("Loading saved theme from config: %s", saved_theme);
80+
}
81+
Theme *theme = load_theme(saved_theme);
82+
if (theme) {
83+
if (current_theme) {
84+
free_theme(current_theme);
85+
}
86+
current_theme = theme;
87+
if (getenv("NUT_DEBUG")) {
88+
DEBUG_LOG("Successfully loaded saved theme: %s", theme->name);
89+
}
90+
} else if (getenv("NUT_DEBUG")) {
91+
DEBUG_LOG("Failed to load saved theme: %s", saved_theme);
92+
}
93+
}
94+
6595
// Initialize the AI shell integration
6696
init_ai_shell();
6797

@@ -245,6 +275,9 @@ void shell_loop() {
245275

246276
// Clean up theme system
247277
cleanup_theme_system();
278+
279+
// Clean up configuration system
280+
cleanup_config_system();
248281
}
249282

250283
char *get_prompt() {

0 commit comments

Comments
 (0)