From a57a9682e74ff3609acb2ca6697fc6fa94c23fb6 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 20 Apr 2021 14:51:50 -0400 Subject: :set-language, various other little things --- README.md | 22 ++++++++++++---------- buffer.c | 2 ++ command.c | 19 ++++++++++++++++++- command.h | 2 ++ main.c | 2 -- menu.c | 1 + syntax.c | 4 ++-- ted.cfg | 18 +++++++++++++++++- ted.h | 21 ++++++++++++--------- ui.c | 10 ++++++++++ 10 files changed, 76 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9450b98..726f9b1 100644 --- a/README.md +++ b/README.md @@ -19,18 +19,18 @@ in other editors. ## Supported features - Customization of (pretty much) all colours and keyboard commands. -- Basic stuff like copy+paste, undo+redo, etc. +- Basic text editing like copy+paste, undo+redo, etc. - Multiple tabs, each with a different file -- Split screen (default: Ctrl+\\, Ctrl+Shift+\\) +- Split screen - Auto-indent - Syntax highlighting for C, C++, HTML, LaTeX, Markdown, Python, and Rust. - Find and replace (with regular expressions!) -- Run build command (F4), go to errors -- Run any shell command (Ctrl+!) -- Go to definition (Ctrl+click) -- Go to line (Ctrl+G) -- Autocomplete (Ctrl+Space) -- Indent/dedent selection (Tab, Shift+Tab), comment/uncomment selection (Ctrl+/) +- Run build command, go to errors +- Run any shell command +- Go to definition +- Go to line number +- Autocomplete +- Indent/dedent selection, comment/uncomment selection ## Getting started with ted @@ -81,7 +81,9 @@ in the `[core]` section of the config file. Jump to definition and autocompletion both depend on [ctags](https://github.com/universal-ctags/ctags). You can press Ctrl+T at any time to generate or re-generate tags. Once you have a tags file, you can Ctrl+Click on an identifier to go to its definition. You can also press Ctrl+D to get a searchable list of all functions/types where you can select one to go to -its definition. Press Ctrl+space to autocomplete. If there is only one possible completion from the tags file, it will be selected automatically. +its definition. + +Press Ctrl+space to autocomplete. If there is only one possible completion from the tags file, it will be selected automatically. Otherwise, you'll get a popup showing all possible completions. You can press tab to select a completion (or click on it), and press Ctrl+space/Ctrl+shift+space to cycle between suggestions. Note that autocomplete just completes to stuff in the tags file, so it won't complete local variable names. Sorry. @@ -110,7 +112,7 @@ sudo make install -j4 On Windows (64-bit), first you will need to install Microsoft Visual Studio, then find and add vcvarsall.bat to your PATH. Next you will need the SDL2 VC development libraries: https://www.libsdl.org/download-2.0.php -Extract the zip, copy SDL2-2.x.y into the ted directory, and rename it to SDL2. Also copy SDL2\lib\x64\SDL2.dll +Extract the zip, copy SDL2-2.x.y into the ted directory, and rename it to SDL2. Also copy SDL2\\lib\\x64\\SDL2.dll to the ted directory. You will also need PCRE2. Download it here: https://ftp.pcre.org/pub/pcre/pcre2-10.36.zip, unzip it, and put pcre2-10.36 in the same folder as ted. diff --git a/buffer.c b/buffer.c index 7e59e06..1e8e697 100644 --- a/buffer.c +++ b/buffer.c @@ -250,6 +250,8 @@ static inline Settings const *buffer_settings(TextBuffer *buffer) { // what programming language is this? Language buffer_language(TextBuffer *buffer) { + if (buffer->manual_language >= 1 && buffer->manual_language <= LANG_COUNT) + return (Language)(buffer->manual_language - 1); Settings const *settings = buffer_settings(buffer); char const *filename = buffer->filename; if (!filename) diff --git a/command.c b/command.c index b706b2d..34aaf0b 100644 --- a/command.c +++ b/command.c @@ -116,6 +116,10 @@ void command_execute(Ted *ted, Command c, i64 argument) { if (ted->replace && buffer == &ted->find_buffer) { ted_switch_to_buffer(ted, &ted->replace_buffer); buffer_select_all(buffer); + } else if (ted->menu == MENU_COMMAND_SELECTOR && buffer == &ted->argument_buffer) { + buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, buffer); + buffer_select_all(buffer); } else if (ted->autocomplete) { autocomplete_select_cursor_completion(ted); } else if (buffer) { @@ -129,6 +133,10 @@ void command_execute(Ted *ted, Command c, i64 argument) { if (ted->replace && buffer == &ted->replace_buffer) { ted_switch_to_buffer(ted, &ted->find_buffer); buffer_select_all(buffer); + } else if (ted->menu == MENU_COMMAND_SELECTOR && buffer == &ted->line_buffer) { + buffer = &ted->argument_buffer; + ted_switch_to_buffer(ted, buffer); + buffer_select_all(buffer); } else if (buffer) { if (buffer->selection) buffer_dedent_selection(buffer); @@ -227,7 +235,15 @@ void command_execute(Ted *ted, Command c, i64 argument) { } } break; - + + case CMD_SET_LANGUAGE: + if (buffer && !buffer->is_line_buffer) { + if (argument < 0 || argument >= LANG_COUNT) + buffer->manual_language = -1; + else + buffer->manual_language = (i16)(argument + 1); + } + break; case CMD_AUTOCOMPLETE: if (ted->autocomplete) ++ted->autocomplete_cursor; @@ -238,6 +254,7 @@ void command_execute(Ted *ted, Command c, i64 argument) { if (ted->autocomplete) --ted->autocomplete_cursor; break; + case CMD_UNDO: if (buffer) buffer_undo(buffer, argument); break; diff --git a/command.h b/command.h index b2da2c5..39f861d 100644 --- a/command.h +++ b/command.h @@ -56,6 +56,7 @@ ENUM_U16 { CMD_RELOAD_ALL, // reload all buffers from file CMD_QUIT, + CMD_SET_LANGUAGE, CMD_AUTOCOMPLETE, CMD_AUTOCOMPLETE_BACK, @@ -143,6 +144,7 @@ static CommandName const command_names[] = { {"save-all", CMD_SAVE_ALL}, {"reload-all", CMD_RELOAD_ALL}, {"quit", CMD_QUIT}, + {"set-language", CMD_SET_LANGUAGE}, {"command-selector", CMD_COMMAND_SELECTOR}, {"open-config", CMD_OPEN_CONFIG}, {"undo", CMD_UNDO}, diff --git a/main.c b/main.c index d140f29..8cf3997 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,3 @@ -// :set-language command; -1 = default language for this extension - #include "base.h" no_warn_start #if _WIN32 diff --git a/menu.c b/menu.c index d363b37..6977552 100644 --- a/menu.c +++ b/menu.c @@ -275,6 +275,7 @@ static void menu_update(Ted *ted) { } } selector->n_entries = (u32)(entry - entries); + selector_sort_entries_by_name(selector); } char *chosen_command = selector_update(ted, &ted->command_selector); diff --git a/syntax.c b/syntax.c index bc8803c..19aca34 100644 --- a/syntax.c +++ b/syntax.c @@ -870,7 +870,7 @@ static void syntax_highlight_markdown(SyntaxState *state, char32_t const *line, } static bool is_html_tag_char(char32_t c) { - return c == '<' || c == '/' || c == '!' || is32_alnum(c); + return c == '<' || c == '/' || c == '!' || c == ':' || is32_alnum(c); } static void syntax_highlight_html(SyntaxState *state, char32_t const *line, u32 line_len, SyntaxCharType *char_types) { @@ -1024,7 +1024,7 @@ static void syntax_highlight_config(SyntaxState *state, char32_t const *line, u3 default: { if (i == 0) // none of the keywords in syntax_all_keywords_config should appear at the start of the line break; - if (is32_ident(line[i - 1]) || !is32_ident(line[i])) + if (is32_ident(line[i-1]) || line[i-1] == '-' || !is32_ident(line[i])) break; // can't be a keyword on its own. u32 keyword_len = syntax_keyword_len(LANG_CONFIG, line, i, line_len); diff --git a/ted.cfg b/ted.cfg index bad356e..87b1c95 100644 --- a/ted.cfg +++ b/ted.cfg @@ -94,6 +94,22 @@ Ctrl+Shift+s = :save-as Ctrl+q = :quit Ctrl+Shift+r = :reload-all +# You can do something like this: +# Ctrl+Alt+t = 3 :set-language +# to set the language of the current buffer to Rust, for example. This might be useful if +# one file extension could be multiple different languages. +# Here are the numbers corresponding to each language we have syntax highlighting for: +# 0 Plain text (no syntax highlighting) +# 1 C +# 2 C++ +# 3 Rust +# 4 Python +# 5 TeX +# 6 Markdown +# 7 HTML +# 8 Config (e.g. ted.cfg) +# -1 Guess from the file extension (default) + Ctrl+Space = :autocomplete # go to previous completion Ctrl+Shift+Space = :autocomplete-back @@ -209,5 +225,5 @@ Rust = .rs Python = .py Tex = .tex Markdown = .md -HTML = .html, .php +HTML = .html, .php, .xml, .xhtml Config = .cfg diff --git a/ted.h b/ted.h index e08f222..941508f 100644 --- a/ted.h +++ b/ted.h @@ -43,16 +43,18 @@ enum { typedef u8 SyntaxState; +// If you are adding new languages, DO NOT change the constant values +// of the previous languages. It will mess up config files! ENUM_U16 { - LANG_NONE, - LANG_C, - LANG_CPP, - LANG_RUST, - LANG_PYTHON, - LANG_TEX, - LANG_MARKDOWN, - LANG_HTML, - LANG_CONFIG, // .cfg files, e.g. ted.cfg + LANG_NONE = 0, + LANG_C = 1, + LANG_CPP = 2, + LANG_RUST = 3, + LANG_PYTHON = 4, + LANG_TEX = 5, + LANG_MARKDOWN = 6, + LANG_HTML = 7, + LANG_CONFIG = 8, // .cfg files, e.g. ted.cfg LANG_COUNT } ENUM_U16_END(Language); @@ -159,6 +161,7 @@ typedef struct { struct Ted *ted; // we keep a back-pointer to the ted instance so we don't have to pass it in to every buffer function double scroll_x, scroll_y; // number of characters scrolled in the x/y direction struct timespec last_write_time; // last write time to filename. + i16 manual_language; // 1 + the language the buffer has been manually set to, or 0 if it hasn't been manually set to anything BufferPos cursor_pos; BufferPos selection_pos; // if selection is true, the text between selection_pos and cursor_pos is selected. bool is_line_buffer; // "line buffers" are buffers which can only have one line of text (used for inputs) diff --git a/ui.c b/ui.c index 0b6a0a0..993a51f 100644 --- a/ui.c +++ b/ui.c @@ -56,6 +56,16 @@ static void selector_down(Ted const *ted, Selector *s, i64 n) { selector_up(ted, s, -n); } +static int selectory_entry_cmp_name(void const *av, void const *bv) { + SelectorEntry const *a = av, *b = bv; + return strcmp(a->name, b->name); +} + +// sort entries alphabetically +static void selector_sort_entries_by_name(Selector *s) { + qsort(s->entries, s->n_entries, sizeof *s->entries, selectory_entry_cmp_name); +} + // returns a null-terminated UTF-8 string of the option selected, or NULL if none was. // you should call free() on the return value. static char *selector_update(Ted *ted, Selector *s) { -- cgit v1.2.3