+++ /dev/null
-# Mouse Shortcuts
-
-# Keyboard Shortcuts
-
-# Tag Commands
-
- Quit - Quit the editor
- Save - Write the loaded file to disc
- Cut - Cut the selected text to the system clipboard
- Copy - Copy the selected text to the system clipboard
- Paste - Paste the contents of the system clipboard
- Undo - Undo the most recent edit
- Redo - Redo the most recently undone operation
- Find - Search for literal text in the file
+++ /dev/null
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "PICK" "1" "May 2017" "" ""
-.
-.SH "NAME"
-\fBpick\fR \- fuzzy find an item from a list of items
-.
-.SH "SYNOPSIS"
-\fBpick\fR [\fIquery\fR]
-.
-.SH "DESCRIPTION"
-\fBpick\fR Takes a list of items on standard input delimited by newlines and an optional initial \fIquery\fR\. A gui window is then presented to the user which allows the user to filter the list using a fuzzy\-find algorithm\. The user\'s selection is printed to standard output upon completion\. If no option is selected \fBpick\fR exits with no output\.
-.
-.SS "Fuzzy\-Find Algorithm"
-TODO: Document this
-.
-.SH "ENVIRONMENT"
-.
-.TP
-\fBPICKTITLE\fR
-If this variable is set its contents are used to populate the status region of the \fBpick\fR window\.
-.
-.SH "AUTHOR"
-Michael D\. Lowis
-.
-.SH "SEE ALSO"
-tide(1) pick(1) pickfile(1) picktag(1)
+++ /dev/null
-# pick -- fuzzy find an item from a list of items
-
-## SYNOPSIS
-
-`pick` [_query_]
-
-## DESCRIPTION
-
-`pick` Takes a list of items on standard input delimited by newlines and an
-optional initial _query_. A gui window is then presented to the user which
-allows the user to filter the list using a fuzzy-find algorithm. The user's
-selection is printed to standard output upon completion. If no option is
-selected `pick` exits with no output.
-
-### Fuzzy-Find Algorithm
-
-TODO: Document this
-
-## ENVIRONMENT
-
-* `PICKTITLE`:
- If this variable is set its contents are used to populate the status region
- of the `pick` window.
-
-## AUTHOR
-
-Michael D. Lowis
-
-## SEE ALSO
-
-tide(1) pick(1) pickfile(1) picktag(1)
+++ /dev/null
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "PICKFILE" "1" "May 2017" "" ""
-.
-.SH "NAME"
-\fBpickfile\fR \- fuzzy find a file from the current directory tree
-.
-.SH "SYNOPSIS"
-.
-.SH "DESCRIPTION"
-.
-.SH "OPTIONS"
-.
-.SH "FILES"
-.
-.SH "ENVIRONMENT"
-.
-.SH "DIAGNOSTICS"
-.
-.SH "BUGS"
-.
-.SH "AUTHOR"
-.
-.SH "SEE ALSO"
-
+++ /dev/null
-# pickfile -- fuzzy find a file from the current directory tree
-## SYNOPSIS
-## DESCRIPTION
-## OPTIONS
-## FILES
-## ENVIRONMENT
-## DIAGNOSTICS
-## BUGS
-## AUTHOR
-## SEE ALSO
+++ /dev/null
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "XTAGPICK" "1" "May 2017" "" ""
-.
-.SH "NAME"
-\fBxtagpick\fR \- Parses a ctags file and sends results to pick(1)
-.
-.SH "SYNOPSIS"
-.
-.SH "DESCRIPTION"
-.
-.SH "OPTIONS"
-.
-.SH "FILES"
-.
-.SH "ENVIRONMENT"
-.
-.SH "DIAGNOSTICS"
-.
-.SH "BUGS"
-.
-.SH "AUTHOR"
-.
-.SH "SEE ALSO"
-
+++ /dev/null
-# xtagpick -- Parses a ctags file and sends results to pick(1)
-## SYNOPSIS
-## DESCRIPTION
-## OPTIONS
-## FILES
-## ENVIRONMENT
-## DIAGNOSTICS
-## BUGS
-## AUTHOR
-## SEE ALSO
+++ /dev/null
-#!/bin/bash
-
-edit(){
- # setup editor env
- export PATH="$HOME/.config/edit/tools:$PATH"
- export EDITRCFILE="$HOME/.config/edit/editrc"
- export BASH_ENV="$EDITRCFILE"
- [[ -f "$EDITRCFILE" ]] && . "$EDITRCFILE"
-
- # Now figure out the correct editor to execute
- if [[ -z "$DISPLAY" ]]; then
- "$EDITOR" "$@"
- else
- # Launch in the background and disown
- { tide "$@" & disown; } &> /dev/null
- fi
-}
-
-# Tag Lines
-#------------------------------------------------------------------------------
-
-csrc(){ echo -n "Quit Save Eol rctags !term >lines |bc |uc {>Grep } Find "; }
-src(){ echo -n "Quit Save Eol rctags !term >lines |bcmt |ucmt {>Grep } Find "; }
-ptext(){ echo -n "Quit Save Eol rctags !term |fmt >words {>Grep } Find "; }
-
-# setup default tags line
-export EDITTAGS="$(csrc)"
-
-# Tool Functions
-#------------------------------------------------------------------------------
-
-# Launch a terminal emulator in the same dir as the editor
-term(){ (nohup st)& }
-
-# Regex search
-Grep(){ grep -n "$@"; }
-
-# Refresh ctags file
-rctags(){ ctags -R --exclude="Build"; }
-
-# Word and Line Counts
-words(){ wc -w; }
-lines(){ wc -l; }
-
-# Block Comments for C and Scripting Languages
-bc(){ sed -e 's/^/\/\//'; }
-uc(){ sed -e 's/^\(\s*\)\/\//\1/'; }
-bcmt(){ sed -e 's/^/#/'; }
-ucmt(){ sed -e 's/^\(\s*\)#/\1/'; }
-
-# Expand tabs to spaces
-etabs(){ sed -e 's/\t/ /g'; }
-
-# Add a line number to each line of the file
-lnnum(){ nl -nln -ba; }
-
-# Trim trailing whitspace
-trim(){ sed -e 's/[\t ]\+$//'; }
-
-# Hex editing functions
-hex(){ xxd; }
-nohex(){ xxd -r; }
+++ /dev/null
-set args testdocs/sherlock.txt
-run
-bt
+++ /dev/null
-#include <stdc.h>
-#include <x11.h>
-#include <utf.h>
-#include <edit.h>
-#include <win.h>
-#include <vec.h>
-#include <ctype.h>
-#include <shortcuts.h>
-
-typedef struct {
- float score;
- char* string;
- size_t length;
- size_t match_start;
- size_t match_end;
-} Choice;
-
-static unsigned Pos = 0;
-static vec_t Choices = {0};
-static size_t ChoiceIdx = 0;
-
-static char* rdline(FILE* fin) {
- if (feof(fin) || ferror(fin))
- return NULL;
- size_t size = 256;
- size_t index = 0;
- char* str = (char*)malloc(size);
- while (true) {
- char ch = fgetc(fin);
- if (ch == EOF) break;
- str[index++] = ch;
- str[index] = '\0';
- if (index+1 >= size) {
- size = size << 1;
- str = realloc(str, size);
- }
- if (ch == '\n') break;
- }
- return str;
-}
-
-static int by_score(const void* a, const void* b) {
- Choice* ca = ((Choice*)a);
- Choice* cb = ((Choice*)b);
- if (ca->score < cb->score)
- return 1;
- else if (ca->score > cb->score)
- return -1;
- else
- return strcmp(ca->string, cb->string);
-}
-
-static void load_choices(void) {
- char* choice_text;
- Choice choice = {0};
- vec_init(&Choices, sizeof(Choice));
- while ((choice_text = rdline(stdin)) != NULL) {
- choice_text[strlen(choice_text)-1] = '\0';
- if (strlen(choice_text) > 0) {
- choice.string = choice_text;
- choice.length = strlen(choice_text);
- choice.score = 1.0;
- vec_push_back(&Choices, &choice);
- } else {
- free(choice_text);
- }
- }
- vec_sort(&Choices, by_score);
-}
-
-static char* find_match_start(char *str, int ch) {
- for (; *str; str++)
- if (tolower(*str) == tolower(ch))
- return str;
- return NULL;
-}
-
-static bool match(char *string, size_t offset, size_t *start, size_t *end) {
- Buf* buf = win_buf(TAGS);
- unsigned qpos = 0;
- char* s = find_match_start(&string[offset], buf_get(buf, qpos));
- char* e = s;
- /* bail if no match for first char */
- if (s == NULL) return 0;
- /* find the end of the match */
- for (unsigned bend = buf_end(buf); qpos < bend; qpos++)
- if ((e = find_match_start(e, buf_get(buf, qpos))) == NULL)
- return false;
- /* make note of the matching range */
- *start = s - string;
- *end = e - string;
- /* Less than or equal is used in order to obtain the left-most match. */
- if (match(string, offset + 1, start, end) && (size_t)(e - s) <= *end - *start) {
- *start = s - string;
- *end = e - string;
- }
- return true;
-}
-
-static void score(void) {
- Buf* buf = win_buf(TAGS);
- for (int i = 0; i < vec_size(&Choices); i++) {
- Choice* choice = (Choice*)vec_at(&Choices, i);
- float qlen = (float)buf_end(buf);
- if (match(choice->string, 0, &choice->match_start, &choice->match_end)) {
- float clen = (float)(choice->match_end - choice->match_start);
- choice->score = qlen / clen / (float)(choice->length);
- } else {
- choice->match_start = 0;
- choice->match_end = 0;
- choice->score = 0.0f;
- }
- }
- vec_sort(&Choices, by_score);
-}
-
-void onmouseleft(WinRegion id, bool pressed, size_t row, size_t col) {
-}
-
-void onmousemiddle(WinRegion id, bool pressed, size_t row, size_t col) {
-}
-
-void onmouseright(WinRegion id, bool pressed, size_t row, size_t col) {
-}
-
-void onscroll(double percent) {
- ChoiceIdx = (size_t)((double)vec_size(&Choices) * percent);
- if (ChoiceIdx >= vec_size(&Choices))
- ChoiceIdx = vec_size(&Choices)-1;
-}
-
-void onfocus(bool focused) {
-}
-
-void onupdate(void) {
- win_setregion(TAGS);
- win_settext(EDIT, "");
- View* view = win_view(EDIT);
- view->selection = (Sel){0,0,0};
- Sel selection = (Sel){0,0,0};
-
- score();
- unsigned off = (ChoiceIdx >= view->nrows ? ChoiceIdx-view->nrows+1 : 0);
- for (int i = 0; (i < vec_size(&Choices)) && (i < view->nrows); i++) {
- unsigned beg = view->selection.end;
- Choice* choice = (Choice*)vec_at(&Choices, i+off);
- for (char* str = choice->string; str && *str; str++)
- view_insert(view, false, *str);
- view_insert(view, false, '\n');
- if (ChoiceIdx == i+off) {
- selection.beg = view->selection.end;
- selection.end = beg;
- }
- }
- view->selection = selection;
-}
-
-void onlayout(void) {
- /* update scroll bar */
- View* view = win_view(EDIT);
- unsigned off = (ChoiceIdx >= view->nrows ? ChoiceIdx-view->nrows+1 : 0);
- double visible = (double)(win_view(EDIT)->nrows);
- double choices = (double)vec_size(&Choices);
- double current = (double)off;
- if (choices > visible)
- win_setscroll(current/choices, visible/choices);
- else
- win_setscroll(0.0, 1.0);
-}
-
-void onshutdown(void) {
- x11_deinit();
-}
-
-/* Main Routine
- *****************************************************************************/
-static void onerror(char* msg) {
-
-}
-
-static void accept(void) {
- x11_deinit();
-}
-
-static void reject(void) {
- ChoiceIdx = SIZE_MAX;
- x11_deinit();
-}
-
-static void select_up(void) {
- if (ChoiceIdx > 0) ChoiceIdx--;
-}
-
-static void select_dn(void) {
- if (ChoiceIdx < vec_size(&Choices)-1) ChoiceIdx++;
-}
-
-static KeyBinding Bindings[] = {
- { ModAny, '\b', backspace },
- { ModAny, '\n', accept },
- { ModCtrl, 'u', del_to_bol },
- { ModCtrl, 'k', del_to_eol },
- { ModCtrl, 'w', del_to_bow },
- { ModCtrl, 'a', cursor_bol },
- { ModCtrl, 'e', cursor_eol },
- { ModCtrl, 'x', cut },
- { ModCtrl, 'c', copy },
- { ModCtrl, 'v', paste },
- { ModCtrl, 'z', undo },
- { ModCtrl, 'y', redo },
- { ModAny, KEY_ESCAPE, reject },
- { ModAny, KEY_DELETE, delete },
- { ModAny, KEY_BACKSPACE, backspace },
- { ModAny, KEY_UP, select_up },
- { ModAny, KEY_DOWN, select_dn },
- { ModAny, KEY_LEFT, cursor_left },
- { ModAny, KEY_RIGHT, cursor_right },
- { ModAny, KEY_HOME, cursor_home },
- { ModAny, KEY_END, cursor_end },
- { 0, 0, 0 }
-};
-
-#ifndef TEST
-int main(int argc, char** argv) {
- load_choices();
- if (vec_size(&Choices) > 1) {
- win_window("pick", true, onerror);
- win_setkeys(Bindings, NULL);
- if (argc >= 2) {
- for (char* str = argv[1]; *str; str++)
- buf_insert(win_buf(TAGS), false, Pos++, *str);
- score();
- view_eof(win_view(TAGS), NULL);
- }
- win_loop();
- }
- /* print out the choice */
- if (vec_size(&Choices) && ChoiceIdx != SIZE_MAX) {
- Choice* choice = (Choice*)vec_at(&Choices, ChoiceIdx);
- puts(choice->string);
- }
- return 0;
-}
-#endif
-
+++ /dev/null
-#!/bin/sh
-if [ "$#" -ne 1 ]; then
- echo "Usage: $0 <dir>"
- exit 1
-fi
-
-export PICKTITLE="Pick File ($PWD)"
-file="$(find $1 -not -path '*/\.*' -type f | sed 's|^\./||' | pick)"
-tctl "$file"
+++ /dev/null
-#!/bin/sh
-ACTION="$1"
-TAGFILE="$2"
-TAG="$3"
-
-usage(){
- echo "Usage: $0 ACTION TAGFILE [TAG]"
- echo ""
- echo "Actions:"
- echo " fetch - Print the filename and line number of the selcted tag"
- echo " print - Print the selected tag"
- exit 1
-}
-
-if [ "" == "$TAGFILE" ] || [ "" == "$ACTION" ]; then
- usage
-fi
-
-printtags(){
- cat "$TAGFILE" | grep -v '^!' | cut -f1 | uniq
-}
-
-print(){
- printf "%s" "$(printtags | pick "$TAG")"
-}
-
-fetch(){
- if [ "" == "$TAG" ]; then
- TAG=$(printtags | pick)
- [ "" == "$TAG" ] && exit
- fi
- file=$(awk -v TAG="$TAG" '
- BEGIN { FS = "[\t]+" }
- ($1 == TAG) {
- matchstr = $3
- sub(/^\//, "\"", matchstr)
- sub(/\$?\/;"$/, "\"", matchstr)
- gsub(/\*/, "\\*", matchstr)
- gsub(/(\[|\])/, "\\\1", matchstr)
- print "grep -Hn", matchstr, $2, "| cut -d: -f1,2"
- }
- ' "$TAGFILE" | /bin/sh | pick)
- [ "" != "$file" ] && tctl "$file"
-}
-
-export PICKTITLE="Pick CTag ($PWD)"
-case "$ACTION" in
- "print") print ;;
- "fetch") fetch ;;
- *) usage ;;
-esac
+++ /dev/null
-#!/bin/bash
-
-# setup editor env
-export PS1=":; "
-export PATH="$HOME/.config/tide/tools:$HOME/bin:$PATH"
-export EDITRCFILE="$HOME/.config/edit/editrc"
-export BASH_ENV="$EDITRCFILE"
-export PROMPT_COMMAND='tide_cd "$PWD"'
-
-# Provide a cd function to change tide's working directory manually. This could
-# be aliased or defined to cd but that interferes with some programs like rbenv.
-function tide_cd(){ echo -en "\033P$PWD\a"; }
-export -f tide_cd
-
-edit(){
- [[ -f "$EDITRCFILE" ]] && . "$EDITRCFILE"
-
- # Now figure out the correct editor to execute
- if [[ -z "$DISPLAY" ]]; then
- "$EDITOR" "$@"
- else
- bkg tide "$@"
- fi
-}
-export -f edit
-
-exec tide --
+++ /dev/null
-#include <stdc.h>
-#include <utf.h>
-#include <edit.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xft/Xft.h>
-#include <unistd.h>
-
-struct {
- Display* display;
- Window root;
- Window self;
- int error;
-} X;
-
-size_t WinCount;
-Window* Windows;
-char** WinFiles;
-
-static void get_windows(Window** wins, char*** files, size_t* nwins);
-static int error_handler(Display* disp, XErrorEvent* ev);
-static void* prop_get(Window win, char* propname, Atom type, unsigned long* nitems);
-static void prop_set(Window win, char* propname, Atom type, int format, void* items, unsigned long nitems);
-static void edit(char* path);
-static Window win_byfile(char* path);
-static void focus_window(Window w, char* addr);
-static void get_abspath(char* path, char** abspath, char** addr);
-
-/* Main Routine
- ******************************************************************************/
-int main(int argc, char** argv) {
- if (!(X.display = XOpenDisplay(0)))
- die("could not open display");
- X.root = DefaultRootWindow(X.display);
- X.self = XCreateSimpleWindow(X.display, X.root, 0, 0, 1, 1, 0, 0, 0);
- XSetErrorHandler(error_handler);
- get_windows(&Windows, &WinFiles, &WinCount);
-
- for (int i = 1; i < argc; i++) {
- bool last = (i == argc-1);
- char *orig = argv[i], *path = NULL, *addr = NULL;
- get_abspath(orig, &path, &addr);
-
- Window win = win_byfile(path);
- if (!win) {
- fprintf(stderr, "edit(%s)\n", argv[i]);
- edit(argv[i]);
- } else if (last) {
- fprintf(stderr, "focus(%#x,%s)\n", (int)win, addr);
- focus_window(win, addr);
- }
- free(path);
- }
-
- XFlush(X.display);
- return 0;
-}
-
-static void get_windows(Window** wins, char*** files, size_t* nwins) {
- XGrabServer(X.display);
- unsigned long nwindows = 0, nactive = 0, nstrings = 0;
- Window *windows = prop_get(X.root, "TIDE_WINDOWS", XA_WINDOW, &nwindows);
- Window *active = calloc(nwindows, sizeof(Window));
- char **wfiles = calloc(nwindows, sizeof(char*));
- Atom xa_comm = XInternAtom(X.display, "TIDE_COMM", False);
- for (int i = 0; i < nwindows; i++) {
- X.error = 0;
- int nprops;
- Atom* props = XListProperties(X.display, windows[i], &nprops);
- if (!props || X.error) continue;
- for (int x = 0; x < nprops; x++) {
- if (props[x] == xa_comm) {
- active[nactive] = windows[i];
- wfiles[nactive] = prop_get(windows[i], "TIDE_FILE", XA_STRING, &nstrings);
- nactive++;
- break;
- }
- }
- XFree(props);
- }
- prop_set(X.root, "TIDE_WINDOWS", XA_WINDOW, 32, active, nactive);
- XSync(X.display, False);
- XUngrabServer(X.display);
- XFree(windows);
- *wins = active, *files = wfiles, *nwins = nactive;
-}
-
-static int error_handler(Display* disp, XErrorEvent* ev) {
- X.error = ev->error_code;
- return 0;
-}
-
-static void* prop_get(Window win, char* propname, Atom type, unsigned long* nitems) {
- Atom rtype, prop = XInternAtom(X.display, propname, False);
- unsigned long rformat = 0, nleft = 0;
- unsigned char* data = NULL;
- XGetWindowProperty(X.display, win, prop, 0, -1, False, type, &rtype,
- (int*)&rformat, nitems, &nleft, &data);
- if (rtype != type)
- data = NULL, *nitems = 0;
- return data;
-}
-
-static void prop_set(Window win, char* propname, Atom type, int format, void* items, unsigned long nitems) {
- Atom prop = XInternAtom(X.display, propname, False);
- XChangeProperty(X.display, win, prop, type, format, PropModeReplace, items, (int)nitems);
-}
-
-static void edit(char* path) {
- if (fork() == 0)
- exit(execvp("tide", (char*[]){ "tide", path, NULL }));
-}
-
-static Window win_byfile(char* path) {
- for (int i = 0; i < WinCount; i++)
- if (WinFiles[i] && !strcmp(path, WinFiles[i]))
- return Windows[i];
- return (Window)0;
-}
-
-static void focus_window(Window w, char* addr) {
- XEvent ev = {0};
- ev.xclient.type = ClientMessage;
- ev.xclient.send_event = True;
- ev.xclient.message_type = XInternAtom(X.display, "_NET_ACTIVE_WINDOW", False);
- ev.xclient.window = w;
- ev.xclient.format = 32;
- long mask = SubstructureRedirectMask | SubstructureNotifyMask;
- XSendEvent(X.display, X.root, False, mask, &ev);
- XMapRaised(X.display, w);
- if (addr && *addr)
- prop_set(w, "TIDE_COMM", XA_STRING, 8, addr, strlen(addr));
- XFlush(X.display);
-}
-
-void get_abspath(char* path, char** abspath, char** addr) {
- path = stringdup(path);
- char* faddr = strrchr(path, ':');
- if (faddr) *(faddr++) = '\0';
- char* rpath = realpath(path, NULL);
- if (!rpath) rpath = path;
- *abspath = rpath, *addr = faddr;
-}
+++ /dev/null
-#define _XOPEN_SOURCE 700
-#include <stdc.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <regex.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#ifdef __MACH__
- #define OPENCMD "open"
-#else
- #define OPENCMD "xdg-open"
-#endif
-
-typedef struct {
- enum {
- COMPLETE=0, MATCHES, IS, ISSET, ISDIR, ISFILE,
- SET, UNSET, FINDFILE, EXEC, LAUNCH
- } type;
- char* arg1;
- char* arg2;
-} Rule;
-
-char* Matches[10];
-
-Rule* BuiltinRules[] = {
- (Rule[]){ // Look up .c or .h files in Code/
- { ISSET, "EDITOR", NULL },
- { MATCHES, "data", "\\.[ch]$" },
- { ISDIR, "Code", NULL },
- { EXEC, "[[ $(find Code -type f -name '*$data') ]]", NULL },
- { LAUNCH, "find Code -type f -name '*$data' | xargs -r $EDITOR", NULL },
- { COMPLETE, NULL, NULL }
- },
- (Rule[]){ // Match URLS and open them with the browser
- { ISSET, "BROWSER", NULL },
- { MATCHES, "data", "^(https?|ftp)://.*" },
- { LAUNCH, "$BROWSER $0", NULL },
- { COMPLETE, NULL, NULL }
- },
- (Rule[]){ // Open files with addresses in the editor
- { ISSET, "EDITOR", NULL },
- { MATCHES, "data", "^([^:]+):([0-9]+)" },
- { ISFILE, "$1", NULL },
- { LAUNCH, "tctl $0", NULL },
- { COMPLETE, NULL, NULL }
- },
- (Rule[]){ // If it's an existing text file, open it with editor
- { ISSET, "EDITOR", NULL },
- { ISFILE, "$data", NULL },
- { EXEC, "file --mime '$file' | grep -q 'text/'", NULL },
- { LAUNCH, "$EDITOR '$file'", NULL },
- { COMPLETE, NULL, NULL }
- },
- (Rule[]){ // Look it up in ctags database
- { ISSET, "EDITOR", NULL },
- { ISFILE, "tags", NULL },
- { EXEC, "grep -q '^$data\\s\\+' tags", NULL },
- { LAUNCH, "picktag fetch tags '$data' | xargs -r tide", NULL },
- { COMPLETE, NULL, NULL }
- },
- (Rule[]){ // If it's an existing directory, open it with system default
- { ISDIR, "$data", NULL },
- { LAUNCH, OPENCMD " $data", NULL },
- { COMPLETE, NULL, NULL }
- },
-};
-
-/******************************************************************************/
-
-char* getvar(char* val) {
- if (strlen(val) == 1 && isdigit(*val))
- val = Matches[*val - '0'];
- else
- val = getenv(val);
- return (val ? val : "");
-}
-
-char* eval(char* str) {
- static bool inited = false;
- static char* patt = "\\$([a-zA-Z0-9_]+)";
- static regex_t regex;
-
- if (!inited && (regcomp(®ex, patt, REG_EXTENDED) < 0)) {
- perror("regcomp() :");
- exit(1);
- }
-
- regmatch_t matches[2] = {0};
- if (regexec(®ex, str, nelem(matches), matches, 0) < 0) {
- return str;
- } else if (matches[1].rm_so > 0) {
- char* var = strndup(str+matches[1].rm_so, matches[1].rm_eo-matches[1].rm_so);
- char* val = getvar(var);
- size_t sz = strlen(str) + strlen(val);
- char* exp = calloc(1, sz);
- strncat(exp, str, matches[0].rm_so);
- strcat(exp, val);
- strcat(exp, str + matches[0].rm_eo);
- return eval(exp);
- } else {
- return str;
- }
-}
-
-/******************************************************************************/
-
-bool complete(void) {
- exit(0);
- return false;
-}
-
-bool matches(char* var, char* patt) {
- regex_t regex = {0};
- regmatch_t matches[10] = {0};
- if (regcomp(®ex, patt, REG_EXTENDED) == 0) {
- var = getvar(var);
- memset(Matches, 0, sizeof(Matches));
- int err = regexec(®ex, var, nelem(matches), matches, 0);
- for (int i = 0; i < 10 && matches[i].rm_so >= 0; i++) {
- Matches[i] = strndup(var+matches[i].rm_so, matches[i].rm_eo-matches[i].rm_so);
- }
- return (err == 0);
- }
- return false;
-}
-
-bool var_is(char* var, char* val) {
- return (strcmp(getvar(var), eval(val)) == 0);
-}
-
-bool var_isset(char* var) {
- return (getenv(var) != NULL);
-}
-
-bool var_isdir(char* var) {
- struct stat st = {0};
- char* path = eval(var);
- if ((stat(path, &st) < 0) && (errno == ENOENT)) {
- return false;
- } else if (S_ISDIR(st.st_mode)) {
- setenv("dir", var, 1);
- return true;
- } else {
- return false;
- }
-}
-
-bool var_isfile(char* var) {
- struct stat st = {0};
- char* path = eval(var);
- if ((stat(eval(var), &st) < 0) && (errno == ENOENT)) {
- return false;
- } else if (!S_ISDIR(st.st_mode)) {
- setenv("file", path, 1);
- return true;
- } else {
- return false;
- }
-}
-
-bool var_set(char* var, char* val) {
- return (setenv(var, eval(val), 1) == 0);
-}
-
-bool var_unset(char* var) {
- return (unsetenv(var) == 0);
-}
-
-bool find_file(char* file) {
- return false;
-}
-
-void runcmd(char* cmd) {
- char* shellcmd[] = { getvar("SHELL"), "-c", NULL, NULL };
- if (!shellcmd[0]) shellcmd[0] = "/bin/sh";
- shellcmd[2] = eval(cmd);
- _exit(execvp(shellcmd[0], shellcmd));
-}
-
-bool exec(char* cmd) {
- int pid, status, outpipe[2];
- if ((pid = fork()) < 0) return false;
- if (pid == 0) {
- runcmd(cmd);
- } else {
- waitpid(pid, &status, 0);
- return (status == 0);
- }
- return false;
-}
-
-bool launch(char* cmd) {
- int pid = fork();
- if (pid > 0)
- return true;
- else if (pid == 0)
- runcmd(cmd);
- return false;
-}
-
-bool apply_rule(Rule* rule) {
- switch (rule->type) {
- case COMPLETE: exit(0);
- case MATCHES: return matches(rule->arg1, rule->arg2);
- case IS: return var_is(rule->arg1, rule->arg2);
- case ISSET: return var_isset(rule->arg1);
- case ISDIR: return var_isdir(rule->arg1);
- case ISFILE: return var_isfile(rule->arg1);
- case SET: return var_set(rule->arg1, rule->arg2);
- case UNSET: return var_unset(rule->arg1);
- case FINDFILE: return find_file(rule->arg1);
- case EXEC: return exec(rule->arg1);
- case LAUNCH: return launch(rule->arg1);
- }
- return false;
-}
-
-/******************************************************************************/
-
-void usage(char* pname) {
- fprintf(stderr, "Usage: %s [ITEM]\n", pname);
- exit(1);
-}
-
-int main(int argc, char** argv) {
- if (argc != 2) usage(argv[0]);
- setenv("data", argv[1], 1);
- for (int i = 0; i < nelem(BuiltinRules); i++) {
- Rule* rule = BuiltinRules[i];
- for (; rule->type != COMPLETE; rule++) {
- //printf("%d '%s' '%s'\n", rule->type, rule->arg1, rule->arg2);
- if (!apply_rule(rule))
- break;
- }
- //puts("");
- if (rule->type == COMPLETE)
- exit(0);
- }
- return 1;
-}
+++ /dev/null
-!-------------------------------------------------------------------------------
-! Acme Theme - based on the Acme text editor
-!-------------------------------------------------------------------------------
-! Looks closest to Acme with line numbers, ruler, and syntax disabled.
-
-! Setting Tweaks
-tide.ui.syntax_enabled: false
-tide.ui.line_numbers: false
-tide.ui.ruler_column: 0
-
-! Color Palette
-tide.palette.00: 0xffffffea ! 00 (0) - edit background
-tide.palette.01: 0xffeaffff ! 01 (1) - tags background
-tide.palette.02: 0xff9eeeee ! 02 (2) - tags selection background
-tide.palette.03: 0xff99994c ! 03 (3) - scroll background
-tide.palette.04: 0xffeeee9e ! 02 (4) - edit selection background
-tide.palette.05: 0xff000000 ! 05 (5) - edit foreground
-tide.palette.06: 0xff000000 ! 06 (6) - tags foreground
-tide.palette.07: 0xff8888cc ! 07 (7) - horizontal border
-tide.palette.08: 0xff000000
-tide.palette.09: 0xff000000
-tide.palette.10: 0xff000000
-tide.palette.11: 0xff000000
-tide.palette.12: 0xff000000
-tide.palette.13: 0xff000000
-tide.palette.14: 0xff000000
-tide.palette.15: 0xff000000
-
-! override default color pairs and cursors
-tide.colors.tags.selected: 0x0206
-tide.colors.tags.cursor: 0x06
-tide.colors.edit.selected: 0x0405
-tide.colors.edit.cursor: 0x05
-tide.colors.borders: 0x0703
-tide.colors.edit.ruler: 0x03
-tide.colors.gutter.normal: 0x0300
-tide.colors.gutter.selected: 0x0003
+++ /dev/null
-!-------------------------------------------------------------------------------
-! Monokai - Based on default scheme for Sublime Text
-!-------------------------------------------------------------------------------
-! 16-color Palette Definition
-tide.palette.00: 0xff272822
-tide.palette.01: 0xff383830
-tide.palette.02: 0xff49483e
-tide.palette.03: 0xff75715e
-tide.palette.04: 0xffa59f85
-tide.palette.05: 0xfff8f8f2
-tide.palette.06: 0xfff5f4f1
-tide.palette.07: 0xfff9f8f5
-tide.palette.08: 0xfff92672
-tide.palette.09: 0xfffd971f
-tide.palette.10: 0xffCEC56A
-tide.palette.11: 0xffa7a059
-tide.palette.12: 0xffa1efe4
-tide.palette.13: 0xff66d9ef
-tide.palette.14: 0xffae81ff
-tide.palette.15: 0xffcc6633
-
-tide.colors.syntax.normal: 0x0005
-tide.colors.syntax.comment: 0x0003
-tide.colors.syntax.preprocessor: 0x0008
-tide.colors.syntax.keyword: 0x0008
-tide.colors.syntax.type: 0x000D
-tide.colors.syntax.constant: 0x000E
-tide.colors.syntax.number: 0x000E
-tide.colors.syntax.boolean: 0x000E
-tide.colors.syntax.float: 0x000E
-tide.colors.syntax.string: 0x000A
-tide.colors.syntax.character: 0x000A
-tide.colors.syntax.variable: 0x0008
-tide.colors.syntax.operator: 0x000C
-tide.colors.syntax.function: 0x000D
-tide.colors.syntax.statement: 0x000F
-tide.colors.syntax.special: 0x000F
+++ /dev/null
-#!/usr/bin/env ruby
-
-if not ARGV[0] then
- $stderr.puts "Usage: tide-hl.rb [FILE]"
- exit 1
-end
-
-require 'stringio'
-require 'strscan'
-require 'set'
-
-Styles = {
- # Color Palette
- Base03: 0, Yellow: 8,
- Base02: 1, Orange: 9,
- Base01: 2, Red: 10,
- Base00: 3, Magenta: 11,
- Base0: 4, Violet: 12,
- Base1: 5, Blue: 13,
- Base2: 6, Cyan: 14,
- Base3: 7, Green: 15,
-
- # Default Highlight Styles
- Normal: (1 << 4),
- Comment: (2 << 4),
- Constant: (3 << 4),
- String: (4 << 4),
- Char: (5 << 4),
- Number: (6 << 4),
- Boolean: (7 << 4),
- Float: (8 << 4),
- Variable: (9 << 4),
- Function: (10 << 4),
- Keyword: (11 << 4),
- Operator: (12 << 4),
- PreProcessor: (13 << 4),
- Type: (14 << 4),
- Statement: (15 << 4),
- Special: (16 << 4),
-}
-
-$language = nil
-$buf = StringIO.new
-$scan = StringScanner.new("")
-Rules = []
-
-def languages(langmap)
- file = ARGV[0]
- ext = File.extname(file).downcase
- langmap.each do |k,v|
- if (v.member?(ext) || v.member?(file))
- return ($language = k)
- end
- end
-end
-
-def language(name, &block)
- if $language == name
- block.call()
- end
-end
-
-def style_range(spos, epos, style)
- if (Styles[style])
- puts "#{spos},#{epos},#{Styles[style]}"
- end
-end
-
-def style_match(s)
- style_range($scan.pos - $scan.matched_size, $scan.pos, s)
-end
-
-def rule(regex, &block)
- Rules << [regex, block]
-end
-
-def range(start=nil, stop=nil, color=nil)
- rule start do
- beg = $scan.pos - $scan.matched_size
- if not $scan.scan_until stop
- $scan.pos += $scan.rest_size
- end
- style_range(beg, $scan.pos, color)
- end
-end
-
-def match(regex, style)
- Rules << [regex, style]
-end
-
-def match_sets(regex, setmap)
- rule regex do |m|
- setmap.each do |k,v|
- if v.member?(m)
- style_match(k)
- break;
- end
- end
- end
-end
-
-#-------------------------------------------------------------------------------
-
-languages({
- "Ruby" => Set.new(%w[Rakefile Rakefile.rb .rb gpkgfile]),
- "C" => Set.new(%w[.c .h .cpp .hpp .cc .c++ .cxx]),
- "OCaml" => Set.new(%w[.ml .mli]),
-})
-
-language "C" do
- types = Set.new %w[
- bool short int long unsigned signed char size_t
- void extern static inline struct enum typedef union volatile auto const
- int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t
- ]
-
- keywords = Set.new %w[
- goto break return continue asm case default if else switch while for do sizeof
- ]
-
- constants = Set.new %w[
- NULL true false
- ]
-
- range start=/\/\*/, stop=/\*\//, :Comment
- match /\/\/.*$/, :Comment
- match /#\s*\w+/, :PreProcessor
- match /"(\\"|[^"\n])*"/, :String
- match /'(\\.|[^'\n\\])'/, :Char
-
- match_sets /[a-zA-Z_][0-9a-zA-Z_]*/,
- :Type => types, :Keyword => keywords, :Constant => constants
-
- match /0x[0-9a-fA-F]+[ulUL]*/, :Number
- match /[0-9]+[ulUL]*/, :Number
-end
-
-language "Ruby" do
- keywords = Set.new %w[
- if not then else elsif end def do exit nil begin rescue raise pass class
- goto break return continue case default switch while for
- ]
-
- range start=/%[qQrilwWs]\[/, stop=/\]/, :String
- match /#.*$/, :Comment
- match /"(\\"|[^"\n])*"/, :String
- match /'(\\'|[^'\n])*'/, :String
- match /\/(\\\/|[^\/\n])*\//, :String
- match /[A-Z][0-9a-zA-Z_]*/, :Type
- match_sets /[a-z_][0-9a-zA-Z_]*/, :Keyword => keywords
- match /0x[0-9a-fA-F]+/, :Number
- match /[0-9]+/, :Number
-end
-
-language "OCaml" do
- keywords = Set.new %w[
- and as assert begin class constraint do done downto else end exception
- external for fun function functor if in include inherit initializer lazy
- let match method module mutable new object of open or private rec sig struct
- then to try type val virtual when while with
- ]
- constants = Set.new %w[true false ]
- range start=/\(\*/, stop=/\*\)/, :Comment
- match /"(\\"|[^"\n])*"/, :String
- match /'(\\'|[^'\n])*'/, :String
- match /[A-Z][0-9a-zA-Z_]*/, :Type
- match_sets /[a-z_][0-9a-zA-Z_]*/, :Keyword => keywords, :Constant => constants
- match /0x[0-9a-fA-F]+/, :Number
- match /[0-9]+/, :Number
- match /\(\)/, :Constant
-end
-
-#-------------------------------------------------------------------------------
-
-# bail if theres nothing to highlight
-exit 0 if $language.nil?
-
-# otherwise start doing the job
-while (not $stdin.eof?) do
- # Read in the input chunk
- $buf = StringIO.new
- len = $stdin.gets.to_i
- if len > 0
- len.times { $buf << $stdin.getc }
- $scan = StringScanner.new($buf.string)
- # scan the input for rule matches
- while (not $scan.eos?) do
- match = false
- Rules.each do |r|
- if $scan.scan(r[0]) then
- if r[1].class == Symbol
- style_match(r[1])
- else
- r[1].call($scan.matched)
- end
- match = true
- break;
- end
- end
- $scan.pos += 1 if (not match)
- end
- puts "0,0,0"
- $stdout.flush
- end
-end