diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-23 20:12:58 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-23 20:12:58 -0400 |
| commit | 10fa6f4e2e7150ad99827721ada1ae4badcc5e90 (patch) | |
| tree | 960065c8e69f1e7a4150ecf522e2f813c239b5ee /gptel-tools/list_directory_files.el | |
| parent | f4cc70c69e7707dd4a686637e14885f5443fcca6 (diff) | |
| download | dotemacs-10fa6f4e2e7150ad99827721ada1ae4badcc5e90.tar.gz dotemacs-10fa6f4e2e7150ad99827721ada1ae4badcc5e90.zip | |
chore(ai): archive gptel and remove it from the live config
I archived gptel to archive/gptel/ since I rarely use it. Moved there: the six gptel modules (ai-config, ai-conversations, ai-conversations-browser, ai-mcp, ai-quick-ask, ai-rewrite), the gptel-tools/ directory, custom/gptel-prompts.el, their test files and utilities, and the four gptel-only specs.
Scrubbed from the live config: the ai-config require in init.el, which also drops the whole C-; a keymap; the gptel-mode emojify hook in font-config.el; the gptel-tools entries in the Makefile clean target and the coverage runner; and the gptel feature notes in README. Cancelled the open gptel tasks in todo.org (the AI Open Work issues, the feature-extension brainstorm, the velox gptel-magit bug).
ai-term stays. It is the ghostel Claude launcher, independent of gptel.
Verified: every module loads, a batch init launch reaches completion clean, and the full test suite shows only pre-existing coverage failures unrelated to this change.
Diffstat (limited to 'gptel-tools/list_directory_files.el')
| -rw-r--r-- | gptel-tools/list_directory_files.el | 200 |
1 files changed, 0 insertions, 200 deletions
diff --git a/gptel-tools/list_directory_files.el b/gptel-tools/list_directory_files.el deleted file mode 100644 index 8da9ba28..00000000 --- a/gptel-tools/list_directory_files.el +++ /dev/null @@ -1,200 +0,0 @@ -;;; list_directory_files.el --- List directory files for GPTel -*- coding: utf-8; lexical-binding: t; -*- - -;; Copyright (C) 2025 - -;; Author: gptel-tool-writer -;; Keywords: convenience, tools -;; Version: 2.0.0 - -;; This file is not part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;;; Commentary: - -;; This tool provides a comprehensive directory listing function for use within gptel. -;; It lists files and directories with detailed attributes such as size, last modification time, -;; permissions, and executable status, supporting optional recursive traversal and filtering -;; by file extension. -;; -;; Features: -;; - Lists files with Unix-style permissions, size, and modification date -;; - Optional recursive directory traversal -;; - Filter files by extension -;; - Graceful error handling and reporting -;; - Human-readable file sizes and dates - -;;; Code: - -(require 'cl-lib) -(require 'seq) -(require 'subr-x) - -;;; Helper Functions - -(defun list-directory-files--mode-to-permissions (mode) - "Convert numeric MODE to symbolic Unix style permissions string." - (concat - (if (eq (logand #o40000 mode) #o40000) "d" "-") - (mapconcat - (lambda (bit) - (cond ((eq bit ?r) (if (> (logand mode #o400) 0) "r" "-")) - ((eq bit ?w) (if (> (logand mode #o200) 0) "w" "-")) - ((eq bit ?x) (if (> (logand mode #o100) 0) "x" "-")))) - '(?r ?w ?x) "") - (mapconcat - (lambda (bit) - (cond ((eq bit ?r) (if (> (logand mode #o040) 0) "r" "-")) - ((eq bit ?w) (if (> (logand mode #o020) 0) "w" "-")) - ((eq bit ?x) (if (> (logand mode #o010) 0) "x" "-")))) - '(?r ?w ?x) "") - (mapconcat - (lambda (bit) - (cond ((eq bit ?r) (if (> (logand mode #o004) 0) "r" "-")) - ((eq bit ?w) (if (> (logand mode #o002) 0) "w" "-")) - ((eq bit ?x) (if (> (logand mode #o001) 0) "x" "-")))) - '(?r ?w ?x) ""))) - -(defun list-directory-files--get-file-info (filepath) - "Get file information for FILEPATH as a plist." - (condition-case err - (let* ((attrs (file-attributes filepath 'string)) - (size (file-attribute-size attrs)) - (last-mod (file-attribute-modification-time attrs)) - (dirp (eq t (file-attribute-type attrs))) - (mode (file-modes filepath)) - (perm (list-directory-files--mode-to-permissions mode)) - (execp (file-executable-p filepath))) - (list :success t - :path filepath - :size size - :last-modified last-mod - :is-directory dirp - :permissions perm - :executable execp)) - (error - (list :success nil - :path filepath - :error (error-message-string err))))) - -(defun list-directory-files--filter-by-extension (extension) - "Create a filter function for files with EXTENSION." - (when extension - (lambda (file-info) - (or (plist-get file-info :is-directory) ; Always include directories - (and (plist-get file-info :success) - (string-suffix-p (concat "." extension) - (file-name-nondirectory (plist-get file-info :path)) - t)))))) - -(defun list-directory-files--format-file-entry (file-info base-path) - "Format a single FILE-INFO entry relative to BASE-PATH." - (format " %s%s %10s %s %s" - (plist-get file-info :permissions) - (if (plist-get file-info :executable) "*" " ") - (file-size-human-readable (or (plist-get file-info :size) 0)) - (format-time-string "%Y-%m-%d %H:%M" (plist-get file-info :last-modified)) - (file-relative-name (plist-get file-info :path) base-path))) - -;;; Core Implementation - -(defun list-directory-files--list-directory (path &optional recursive filter max-depth current-depth) - "List files in PATH directory. -RECURSIVE enables subdirectory traversal. -FILTER is a predicate function for filtering files. -MAX-DEPTH limits recursion depth (nil for unlimited). -CURRENT-DEPTH tracks the current recursion level." - (let ((files '()) - (errors '()) - (current-depth (or current-depth 0)) - (expanded-path (expand-file-name (or path ".") "~"))) - - (if (not (file-directory-p expanded-path)) - ;; Return error if not a directory - (list :files nil - :errors (list (format "Not a directory: %s" expanded-path))) - ;; Process directory - (condition-case err - (dolist (entry (directory-files expanded-path t "^\\([^.]\\|\\.[^.]\\|\\.\\..\\)")) - (let ((info (list-directory-files--get-file-info entry))) - (if (plist-get info :success) - (progn - ;; Add file if it passes the filter - (when (or (not filter) (funcall filter info)) - (push info files)) - ;; Recurse into directories if needed - (when (and recursive - (plist-get info :is-directory) - (or (not max-depth) (< current-depth max-depth))) - (let ((subdir-result (list-directory-files--list-directory - entry recursive filter max-depth (1+ current-depth)))) - (setq files (nconc files (plist-get subdir-result :files))) - (setq errors (nconc errors (plist-get subdir-result :errors)))))) - ;; Handle file access error - (push (format "%s: %s" (plist-get info :path) (plist-get info :error)) errors)))) - (error - (push (format "Error accessing directory %s: %s" expanded-path (error-message-string err)) errors))) - - (list :files (nreverse files) :errors (nreverse errors))))) - -(defun list-directory-files--format-output (path result) - "Format the directory listing RESULT for PATH as a string." - (let ((files (plist-get result :files)) - (errors (plist-get result :errors)) - (base-path (expand-file-name "~"))) - (concat - (when files - (format "Found %d file%s in %s:\n%s" - (length files) - (if (= (length files) 1) "" "s") - path - (mapconcat (lambda (f) (list-directory-files--format-file-entry f base-path)) - files "\n"))) - (when (and files errors) "\n\n") - (when errors - (format "Errors encountered:\n%s" - (mapconcat (lambda (e) (format " - %s" e)) errors "\n"))) - ;; Handle case where there are no files and no errors - (when (and (not files) (not errors)) - (format "No files found in %s" path))))) - -;;; Tool Registration - -(gptel-make-tool - :name "list_directory_files" - :function (lambda (path &optional recursive filter-extension) - "List files in directory PATH. -RECURSIVE enables subdirectory listing. -FILTER-EXTENSION limits results to files with the specified extension." - (let* ((filter (list-directory-files--filter-by-extension filter-extension)) - (result (list-directory-files--list-directory path recursive filter))) - (list-directory-files--format-output (or path ".") result))) - :description "List files in a directory with detailed attributes. Returns formatted listing with permissions, size, modification time." - :args (list '(:name "path" - :type string - :description "Directory path to list (relative to home directory)") - '(:name "recursive" - :type boolean - :description "Recursively list subdirectories" - :optional t) - '(:name "filter-extension" - :type string - :description "Only include files with this extension" - :optional t)) - :category "filesystem" - :confirm nil - :include t) - -;; Automatically add to gptel-tools on load -(add-to-list 'gptel-tools (gptel-get-tool '("filesystem" "list_directory_files"))) - -(provide 'list_directory_files) -;;; list_directory_files.el ends here
\ No newline at end of file |
