aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md17
-rw-r--r--elisp.c31
-rw-r--r--elisp.h5
-rw-r--r--vterm-module.c62
-rw-r--r--vterm-module.h12
-rw-r--r--vterm.el51
6 files changed, 178 insertions, 0 deletions
diff --git a/README.md b/README.md
index 0643f69..40265bb 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,23 @@ And add this to your `init.el`
M-x vterm-create
```
+# Customization
+
+## Colors
+
+Set the `:foreground` and `:background` attributes of the following faces to a
+color you like:
+
+- vterm
+- vterm-color-black
+- vterm-color-red
+- vterm-color-green
+- vterm-color-yellow
+- vterm-color-blue
+- vterm-color-magenta
+- vterm-color-cyan
+- vterm-color-white
+
# Limitations
- No support for scrolling (But you can use tmux/screen to emulate scrolling)
diff --git a/elisp.c b/elisp.c
index 3c9a804..df71327 100644
--- a/elisp.c
+++ b/elisp.c
@@ -54,6 +54,27 @@ emacs_value color_to_rgb_string(emacs_env *env, VTermColor color) {
return env->make_string(env, buffer, 7);
};
+uint8_t hex_to_byte(char *hex) { return strtoul(hex, NULL, 16); }
+
+VTermColor rgb_string_to_color(emacs_env *env, emacs_value string) {
+ VTermColor color;
+ ptrdiff_t len = 8;
+ char buffer[len];
+ char hex[3];
+ env->copy_string_contents(env, string, buffer, &len);
+ hex[0] = buffer[1];
+ hex[1] = buffer[2];
+ color.red = hex_to_byte(hex);
+ hex[0] = buffer[3];
+ hex[1] = buffer[4];
+ color.green = hex_to_byte(hex);
+ hex[0] = buffer[5];
+ hex[1] = buffer[6];
+ color.blue = hex_to_byte(hex);
+
+ return color;
+};
+
void erase_buffer(emacs_env *env) { env->funcall(env, Ferase_buffer, 0, NULL); }
void insert(emacs_env *env, emacs_value string) {
@@ -69,3 +90,13 @@ void toggle_cursor(emacs_env *env, bool visible) {
emacs_value Qvisible = visible ? Qt : Qnil;
env->funcall(env, Fset, 2, (emacs_value[]){Qcursor_type, Qvisible});
}
+
+emacs_value get_hex_color_fg(emacs_env *env, emacs_value face) {
+ return env->funcall(env, Fvterm_face_color_hex, 2,
+ (emacs_value[]){face, Qforeground});
+}
+
+emacs_value get_hex_color_bg(emacs_env *env, emacs_value face) {
+ return env->funcall(env, Fvterm_face_color_hex, 2,
+ (emacs_value[]){face, Qbackground});
+}
diff --git a/elisp.h b/elisp.h
index a37a4c1..33e2e4c 100644
--- a/elisp.h
+++ b/elisp.h
@@ -28,6 +28,7 @@ emacs_value Finsert;
emacs_value Fgoto_char;
emacs_value Fput_text_property;
emacs_value Fset;
+emacs_value Fvterm_face_color_hex;
// Utils
void bind_function(emacs_env *env, const char *name, emacs_value Sfun);
@@ -39,9 +40,13 @@ void put_text_property(emacs_env *env, emacs_value string, emacs_value property,
emacs_value value);
void byte_to_hex(uint8_t byte, char *hex);
emacs_value color_to_rgb_string(emacs_env *env, VTermColor color);
+uint8_t hex_to_byte(char *hex);
+VTermColor rgb_string_to_color(emacs_env *env, emacs_value string);
void erase_buffer(emacs_env *env);
void insert(emacs_env *env, emacs_value string);
void goto_char(emacs_env *env, int pos);
void toggle_cursor(emacs_env *env, bool visible);
+emacs_value get_hex_color_fg(emacs_env *env, emacs_value face);
+emacs_value get_hex_color_bg(emacs_env *env, emacs_value face);
#endif /* ELISP_H */
diff --git a/vterm-module.c b/vterm-module.c
index 4f59cd5..55e0ee9 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -136,6 +136,54 @@ static void term_redraw(struct Term *term, emacs_env *env) {
term_put_caret(term, env, pos.row, pos.col, -offset);
}
+static void term_setup_colors(struct Term *term, emacs_env *env) {
+ VTermState *state = vterm_obtain_state(term->vt);
+ VTermColor fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm));
+ VTermColor bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm));
+
+ vterm_state_set_default_colors(state, &fg, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_black));
+ vterm_state_set_palette_color(state, 0, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_black));
+ vterm_state_set_palette_color(state, 8, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_red));
+ vterm_state_set_palette_color(state, 1, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_red));
+ vterm_state_set_palette_color(state, 9, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_green));
+ vterm_state_set_palette_color(state, 2, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_green));
+ vterm_state_set_palette_color(state, 10, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_yellow));
+ vterm_state_set_palette_color(state, 3, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_yellow));
+ vterm_state_set_palette_color(state, 11, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_blue));
+ vterm_state_set_palette_color(state, 4, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_blue));
+ vterm_state_set_palette_color(state, 12, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_magenta));
+ vterm_state_set_palette_color(state, 5, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_magenta));
+ vterm_state_set_palette_color(state, 13, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_cyan));
+ vterm_state_set_palette_color(state, 6, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_cyan));
+ vterm_state_set_palette_color(state, 14, &bg);
+
+ fg = rgb_string_to_color(env, get_hex_color_fg(env, Qterm_color_white));
+ vterm_state_set_palette_color(state, 7, &fg);
+ bg = rgb_string_to_color(env, get_hex_color_bg(env, Qterm_color_white));
+ vterm_state_set_palette_color(state, 15, &bg);
+}
+
static void term_flush_output(struct Term *term) {
size_t bufflen = vterm_output_get_buffer_current(term->vt);
if (bufflen) {
@@ -293,6 +341,8 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs,
term->vt = vterm_new(rows, cols);
vterm_set_utf8(term->vt, 1);
+ term_setup_colors(term, env);
+
VTermScreen *screen = vterm_obtain_screen(term->vt);
vterm_screen_reset(screen, 1);
@@ -424,6 +474,18 @@ int emacs_module_init(struct emacs_runtime *ert) {
Fgoto_char = env->intern(env, "goto-char");
Fput_text_property = env->intern(env, "put-text-property");
Fset = env->intern(env, "set");
+ Fvterm_face_color_hex = env->intern(env, "vterm-face-color-hex");
+
+ // Faces
+ Qterm = env->intern(env, "vterm");
+ Qterm_color_black = env->intern(env, "vterm-color-black");
+ Qterm_color_red = env->intern(env, "vterm-color-red");
+ Qterm_color_green = env->intern(env, "vterm-color-green");
+ Qterm_color_yellow = env->intern(env, "vterm-color-yellow");
+ Qterm_color_blue = env->intern(env, "vterm-color-blue");
+ Qterm_color_magenta = env->intern(env, "vterm-color-magenta");
+ Qterm_color_cyan = env->intern(env, "vterm-color-cyan");
+ Qterm_color_white = env->intern(env, "vterm-color-white");
// Exported functions
emacs_value fun;
diff --git a/vterm-module.h b/vterm-module.h
index 11c9531..b971592 100644
--- a/vterm-module.h
+++ b/vterm-module.h
@@ -15,6 +15,17 @@ struct Term {
pthread_t thread;
};
+// Faces
+emacs_value Qterm;
+emacs_value Qterm_color_black;
+emacs_value Qterm_color_red;
+emacs_value Qterm_color_green;
+emacs_value Qterm_color_yellow;
+emacs_value Qterm_color_blue;
+emacs_value Qterm_color_magenta;
+emacs_value Qterm_color_cyan;
+emacs_value Qterm_color_white;
+
static bool compare_cells(VTermScreenCell *a, VTermScreenCell *b);
static bool is_key(unsigned char *key, size_t len, char *key_description);
static emacs_value render_text(emacs_env *env, char *string, int len,
@@ -23,6 +34,7 @@ static emacs_value render_text(emacs_env *env, char *string, int len,
static int set_term_prop_cb(VTermProp prop, VTermValue *val, void *user_data);
static void term_redraw(struct Term *term, emacs_env *env);
+static void term_setup_colors(struct Term *term, emacs_env *env);
static void term_flush_output(struct Term *term);
static void term_process_key(struct Term *term, unsigned char *key, size_t len,
VTermModifier modifier);
diff --git a/vterm.el b/vterm.el
index 024167b..a1672a4 100644
--- a/vterm.el
+++ b/vterm.el
@@ -10,6 +10,7 @@
(require 'vterm-module)
(require 'subr-x)
(require 'cl-lib)
+(require 'color)
(defvar vterm-term nil
"Pointer to struct Term.")
@@ -24,6 +25,52 @@
If you use a keybinding with a prefix-key that prefix-key cannot
be send to the terminal.")
+
+(defface vterm
+ '((t :inherit default))
+ "Default face to use in Term mode."
+ :group 'vterm)
+
+(defface vterm-color-black
+ '((t :foreground "black" :background "black"))
+ "Face used to render black color code."
+ :group 'vterm)
+
+(defface vterm-color-red
+ '((t :foreground "red3" :background "red3"))
+ "Face used to render red color code."
+ :group 'vterm)
+
+(defface vterm-color-green
+ '((t :foreground "green3" :background "green3"))
+ "Face used to render green color code."
+ :group 'vterm)
+
+(defface vterm-color-yellow
+ '((t :foreground "yellow3" :background "yellow3"))
+ "Face used to render yellow color code."
+ :group 'vterm)
+
+(defface vterm-color-blue
+ '((t :foreground "blue2" :background "blue2"))
+ "Face used to render blue color code."
+ :group 'vterm)
+
+(defface vterm-color-magenta
+ '((t :foreground "magenta3" :background "magenta3"))
+ "Face used to render magenta color code."
+ :group 'vterm)
+
+(defface vterm-color-cyan
+ '((t :foreground "cyan3" :background "cyan3"))
+ "Face used to render cyan color code."
+ :group 'vterm)
+
+(defface vterm-color-white
+ '((t :foreground "white" :background "white"))
+ "Face used to render white color code."
+ :group 'vterm)
+
(define-derived-mode vterm-mode fundamental-mode "VTerm"
"Mayor mode for vterm buffer."
(buffer-disable-undo)
@@ -102,5 +149,9 @@ be send to the terminal.")
(when (eq major-mode 'vterm-mode)
(vterm-set-size vterm-term (window-body-height) (window-body-width)))))))
+(defun vterm-face-color-hex (face attr)
+ "Return the color of the FACE's ATTR as a hex string."
+ (apply #'color-rgb-to-hex (color-name-to-rgb (face-attribute face attr nil 'default))))
+
(provide 'vterm)
;;; vterm.el ends here