diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | fcomp.c | 8 | ||||
-rw-r--r-- | fcomp.el | 114 |
3 files changed, 81 insertions, 47 deletions
@@ -21,3 +21,9 @@ noasan: $(SRC) clean: rm -f *.o rm -f $(TARGET) + +install: $(TARGET) + @cp -v $(TARGET) /usr/local/bin/$(TARGET) + +uninstall: + @rm -v /usr/local/bin/$(TARGET) @@ -161,7 +161,7 @@ static void print_help(char *argv0) "Set extra invalid chars for tokens"); fprintf(stderr, "%8s %4s %15s %50s\n", "-w", "[..]", "word length", "Set min word length to count as token"); - fprintf(stderr, "%8s %4s %15s %50s\n\n", "-t", "[..]", "toekn length", + fprintf(stderr, "%8s %4s %15s %50s\n\n", "-t", "[..]", "token length", "Set max token length to parse"); fprintf(stderr, "%8s %4s %15s %50s\n", "-d", "", "debug", "Show debug information"); @@ -739,6 +739,8 @@ static int set_input(FILE **f) } *f = stdin; } else if (cfg.filestream) { + if (!cfg.file || strcmp(cfg.file, "") == 0) + return -1; *f = fmemopen(cfg.file, strlen(cfg.file), "r"); } else { *f = fopen(cfg.file, "r"); @@ -767,7 +769,7 @@ static void get_uniq(slist * l, result *r) int main(int argc, char *argv[]) { int rc = 0; - FILE *f; + FILE *f = NULL; slist token_list = { 0 }; slist ref_list = { 0 }; slist *listp = NULL; @@ -831,6 +833,6 @@ int main(int argc, char *argv[]) done: sfree(&token_list); - fclose(f); + if (f) fclose(f); return rc; } @@ -21,23 +21,23 @@ ;;; Commentary: -;; Emacs front-end for fcomp. Get if from https://ubuntos.dynu.net/git/fcomp +;; Emacs front-end for fcomp. Get it from https://ubuntos.dynu.net/git/fcomp ;;; Install: ;; git clone https://ubuntos.dynu.net/git/fcomp && cd fcomp -;; make && sudo ln -s fcomp /usr/local/bin/fcomp # or mv +;; make && make install # install copies the binary under /usr/local/bin ;; In the emacs init file: ;; (add-to-list 'load-path "/your/custom/path") ;; (require 'fcomp) ;; (setq fcomp-path "/your/custom/path/fcomp") -;; (global-set-key (kbd "M-i") 'fcomp-autocomplete) +;; (global-set-key (kbd "C-<tab>") 'fcomp-autocomplete) ;; or with use-package ;; (use-package fcomp ;; :load-path "/your/custom/path" -;; :bind (("M-i" . fcomp-autocomplete)) +;; :bind (("C-<tab>" . fcomp-autocomplete)) ;; :config ;; (setq fcomp-path "/your/custom/path/fcomp")) @@ -52,57 +52,83 @@ (defvar fcomp-extra-valid-chars "") (defvar fcomp-extra-invalid-chars "") -(defun pr () - (message "Status: %s" (process-status "fcomp"))) +(defun empty-string-p (string) + "Return true if the string is empty or nil. Expects string." + (or (null string) + (zerop (length (string-trim string))))) -;; (thing-at-point 'word 'no-properties) -(defun fcomp-filter (proc str) +(defun fcomp--start (query) + "Initiaize fcomp variables" + (setq fcomp--query query) + (setq fcomp--output "")) + +(defun fcomp--filter (proc str) + "Fill the output buffer" (let* ((fcomp-pre - (if (null (process-get proc 'input-word)) + (if (empty-string-p (process-get proc 'input-word)) nil (format "%s" (process-get proc 'input-word))))) - ;; (enable-recursive-minibuffers t)) - ;; (setq result (substring result (* -1 (- (length result) (length word))) nil)) - (progn - (pr) - (setq result - (ido-completing-read - "Complete:" - (remove "" (split-string str "\n")) - nil nil - fcomp-pre)) - (if (null result) - nil - (insert - (string-remove-prefix - (if (null fcomp-pre) - (format "%s" "") - (format "%s" fcomp-pre)) - result)))))) + (setq fcomp--output (concat fcomp--output str)))) + +(defun fcomp--handle-output () + "Handle output buffer" + (let ((initial-input fcomp--query) + (out-string fcomp--output) + (result nil)) + (if (empty-string-p fcomp--output) + nil + (setq result (ido-completing-read + "Complete:" + (remove "" (split-string fcomp--output "\n")) + nil nil + initial-input))) + (if (empty-string-p result) + (message "%s" "No completion candidates") + (insert (string-remove-prefix + (if (empty-string-p initial-input) + (format "%s" "") + (format "%s" initial-input)) + result))) + (setq fcomp--query "") + (setq fcomp--output ""))) (defun fcomp-autocomplete () + "Autocompete using fcomp.c + +When `thing-at-point' is a word, autocomplete it based on buffer contents. + +When invoked with no `thing-at-point' show a list of all possible candidates. + +Requires fcomp. Get it at URL `https://ubuntos.dynu.net/git/fcomp'" + ;; Thanks Dan for the syntax-table trick + ;; https://emacs.stackexchange.com/questions/9583/how-to-treat-underscore-as-part-of-the-word (interactive) - (fcomp--autocomplete (thing-at-point 'word 'no-properties))) + (let ((table (copy-syntax-table (syntax-table)))) + (modify-syntax-entry ?- "w" table) + (with-syntax-table table + (fcomp--autocomplete (thing-at-point 'word 'no-properties))))) (defun fcomp--autocomplete (word) - "Do stuff and ac" - (let ((term (if (null word) - (format "%s" "-au") + "Start fcomp process and orchistrate it's output." + (let ((term (if (empty-string-p word) + (format "%s" "-a") (format "%s" word))) (input (buffer-substring-no-properties (point-min) (point-max)))) - (with-temp-buffer - (set-process-filter - (start-process - "fcomp" - nil - fcomp-path - "-w" (format "%s" fcomp-min-word-length) - "-F" input - "-v" (format "%s" fcomp-extra-valid-chars) - "-i" (format "%s" fcomp-extra-invalid-chars) - term) - #'fcomp-filter) - (process-put (get-process "fcomp") 'input-word word)))) + (fcomp--start word) + (set-process-filter + (start-process + "fcomp" + nil + (format "%s"fcomp-path) + "-w" (format "%s" fcomp-min-word-length) + "-F" (format "%s" input) + "-v" (format "%s" fcomp-extra-valid-chars) + "-i" (format "%s" fcomp-extra-invalid-chars) + term) + #'fcomp--filter) + (process-put (get-process "fcomp") 'input-word word) + (accept-process-output (get-process "fcomp")) + (fcomp--handle-output))) (provide 'fcomp) ;;; fcomp.el ends here |