Coder Social home page Coder Social logo

f.el's People

Contributors

darkfeline avatar dr-scsi avatar dsx avatar ebpa avatar fuco1 avatar github-actions[bot] avatar jaremko avatar leodag avatar marcinant avatar mwfogleman avatar nagy avatar pd avatar phillord-ncl avatar phst avatar phundrak avatar randomwangran avatar rejeep avatar sachac avatar seanfisk avatar sergv avatar shlevy avatar silex avatar spwhitton avatar sviridov avatar swsnr avatar syohex avatar tarsius avatar tmalsburg avatar victorteokw avatar wilfred avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

f.el's Issues

[feature-request + contribution] recursive f-mkdir

Hi,
I was looking for a way to implement recursive mkdir (so mkdir -p). Since the library does not have such a function out of the box, I would like to make a feature request for this. I am not sure how to do feature requests...

I can go one step further, and propose some code which does this. I have called it f-mkdir-recursive. It uses the sneaky f-traverse-upwards function and FILO (push/pop). If it is good, quality-wise, I would like to contribute it to f.el.

(defun f-mkdir-recursive (dir &optional ack-p)
  "Recursively create a directory if it doesn't already exist. The second argument prints 
   an acknowledgment with the path of the newly created directory."
  (interactive)

  (let (dirs-to-mkdir)

    (f-traverse-upwards
     (lambda (path)
       (let ((f-exists-p (f-exists? path)))
         (unless f-exists-p
           (push path dirs-to-mkdir))
         f-exists-p))
     dir)

    (dolist (dir-to-mkdir dirs-to-mkdir)
      (f-mkdir dir-to-mkdir))

    (when (and ack-p dirs-to-mkdir)
      (message "Created directory %s." dir))))

All suggestions about how to make the function more efficient are super welcome. And if the maintainers think I can contribute to f.el, I'll be happy to! I just don't know how contributing code works in terms of the git commands etc....

EDIT: I renamed the function from f-mkdir-p to f-mkdir-recursive since -p in elisp is used for other things (I am still not clear on what these things are, but they definitely don't include recursion).

[Bug]: f-shortdoc.el:31:1:Error: Cannot open load file: No such file or directory, shortdoc

Contact Details

No response

Expected behavior

Hi. I've been getting an error when updating recently. I suspect that this is because shortdoc is only available for more recent versions of Emacs (I'm using version 27.2).

Actual behavior

When updating over the last couple of weeks I get following output.

`Compiling internal form(s) at Wed Jun 8 07:35:09 2022
Leaving directory ‘/home/david/.emacs.d/elpa/f-20220607.1618’

Compiling file /home/david/.emacs.d/elpa/f-20220607.1618/f-shortdoc.el at Wed Jun 8 07:35:09 2022
Entering directory ‘/home/david/.emacs.d/elpa/f-20220607.1618/’
f-shortdoc.el:31:1:Error: Cannot open load file: No such file or directory, shortdoc

Compiling file /home/david/.emacs.d/elpa/f-20220607.1618/f.el at Wed Jun 8 07:35:09 2022`

f.el version

master

Emacs version

27.2

Relevant code or log output

No response

Chmod and chown functionality

Should functionality related to chmod and chown introduced? Making files executable, for example. Emacs has set-file-modes, but it requires an integer for a 2nd argument, which is unintuitive.

Tests broken on Emacs master

Emacs master (and the pretest for 26) have changed the semantics of various file operations due to security concerns, causing several f.el tests to fail. Specifically:

$ make EMACS=/home/p/emacs-master/src/emacs
rm -f f.elc
make unit
make[1]: Entering directory '/home/p/f.el'
cask exec ert-runner
...........................Test f-copy-contents-test/copy-directory backtrace:

  copy-file("/home/p/f.el/test/playgrou
  (if (f-file\? from) (copy-file from to) (if (> emacs-major-version 2
  (if f--guard-paths (if (---truthy\? (let (needle) (let ((list f--gua
  f-copy("/home/p/f.el/test/playground/
  (let ((it (car list))) (f-copy it to))
  (while list (let ((it (car list))) (f-copy it to)) (setq it-index (1
  (let ((list (f-entries from)) (it-index 0)) (while list (let ((it (c
  f-copy-contents("from" "to")
  (let ((default-directory f-test/playground-path)) (mapc (function (l
  (closure (t) nil (let ((default-directory f-test/playground-path)) (
  ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
  ert-run-test(#s(ert-test :name f-copy-contents-test/copy-directory :
  ert-run-or-rerun-test(#s(ert--stats :selector (and t) :tests [#s(ert
  ert-run-tests((and t) (lambda (event-type &rest event-args) (cond ((
  ert-runner/run-tests-batch((and t))
  (let ((stats (ert-runner/run-tests-batch selector))) (kill-emacs (if
  ert-runner/run-tests-batch-and-exit((and t))
  (if ert-runner-verbose (ert-runner/run-tests-batch-and-exit ert-runn
  (let ((test-files (ert-runner--test-files tests)) (test-helper (f-ex
  ert-runner/run()
  apply(ert-runner/run nil)
  commander--handle-command(nil)
  commander-parse(nil)
  (if commander-parsing-done nil (commander-parse (or commander-args (
  eval-buffer(#<buffer  *load*> nil "/home/p
  load-with-code-conversion("/home/p/f.
  load("/home/p/f.el/.cask/27.0/elpa/er
  command-line-1(("-scriptload" "/home/p
  command-line()
  normal-top-level()

Test f-copy-contents-test/copy-directory condition:

    (file-already-exists "File already exists" "/home/p/f.el/test/playground/to")

F...Test f-copy-test/copy-absolute-dir-exists backtrace:

  make-directory-internal("/home/p/f.el
  make-directory("/home/p/f.el/test/pla
  copy-directory("/home/p/f.el/test/pla
  (if (> emacs-major-version 23) (copy-directory from to) (if (f-dir\?
  (if (f-file\? from) (copy-file from to) (if (> emacs-major-version 2
  (if f--guard-paths (if (---truthy\? (let (needle) (let ((list f--gua
  f-copy("/home/p/f.el/test/playground/
  (let ((default-directory f-test/playground-path)) (mapc (function (l
  (closure (t) nil (let ((default-directory f-test/playground-path)) (
  ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
  ert-run-test(#s(ert-test :name f-copy-test/copy-absolute-dir-exists 
  ert-run-or-rerun-test(#s(ert--stats :selector (and t) :tests [#s(ert
  ert-run-tests((and t) (lambda (event-type &rest event-args) (cond ((
  ert-runner/run-tests-batch((and t))
  (let ((stats (ert-runner/run-tests-batch selector))) (kill-emacs (if
  ert-runner/run-tests-batch-and-exit((and t))
  (if ert-runner-verbose (ert-runner/run-tests-batch-and-exit ert-runn
  (let ((test-files (ert-runner--test-files tests)) (test-helper (f-ex
  ert-runner/run()
  apply(ert-runner/run nil)
  commander--handle-command(nil)
  commander-parse(nil)
  (if commander-parsing-done nil (commander-parse (or commander-args (
  eval-buffer(#<buffer  *load*> nil "/home/p
  load-with-code-conversion("/home/p/f.
  load("/home/p/f.el/.cask/27.0/elpa/er
  command-line-1(("-scriptload" "/home/p
  command-line()
  normal-top-level()

Test f-copy-test/copy-absolute-dir-exists condition:

    (file-already-exists "File exists" "/home/p/f.el/test/playground/bar")

F..Test f-copy-test/copy-relative-dir-exists backtrace:

  make-directory-internal("/home/p/f.el
  make-directory("/home/p/f.el/test/pla
  copy-directory("foo" "bar")
  (if (> emacs-major-version 23) (copy-directory from to) (if (f-dir\?
  (if (f-file\? from) (copy-file from to) (if (> emacs-major-version 2
  (if f--guard-paths (if (---truthy\? (let (needle) (let ((list f--gua
  f-copy("foo" "bar")
  (let ((default-directory f-test/playground-path)) (mapc (function (l
  (closure (t) nil (let ((default-directory f-test/playground-path)) (
  ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
  ert-run-test(#s(ert-test :name f-copy-test/copy-relative-dir-exists 
  ert-run-or-rerun-test(#s(ert--stats :selector (and t) :tests [#s(ert
  ert-run-tests((and t) (lambda (event-type &rest event-args) (cond ((
  ert-runner/run-tests-batch((and t))
  (let ((stats (ert-runner/run-tests-batch selector))) (kill-emacs (if
  ert-runner/run-tests-batch-and-exit((and t))
  (if ert-runner-verbose (ert-runner/run-tests-batch-and-exit ert-runn
  (let ((test-files (ert-runner--test-files tests)) (test-helper (f-ex
  ert-runner/run()
  apply(ert-runner/run nil)
  commander--handle-command(nil)
  commander-parse(nil)
  (if commander-parsing-done nil (commander-parse (or commander-args (
  eval-buffer(#<buffer  *load*> nil "/home/p
  load-with-code-conversion("/home/p/f.
  load("/home/p/f.el/.cask/27.0/elpa/er
  command-line-1(("-scriptload" "/home/p
  command-line()
  normal-top-level()

Test f-copy-test/copy-relative-dir-exists condition:

    (file-already-exists "File exists" "/home/p/f.el/test/playground/bar")

F........................................................................................................Test f-move-test/move-absolute-path backtrace:

  rename-file("/home/p/f.el/test/playgr
  (if f--guard-paths (if (---truthy\? (let (needle) (let ((list f--gua
  f-move("/home/p/f.el/test/playground/
  (let ((default-directory f-test/playground-path)) (mapc (function (l
  (closure (t) nil (let ((default-directory f-test/playground-path)) (
  ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
  ert-run-test(#s(ert-test :name f-move-test/move-absolute-path :docum
  ert-run-or-rerun-test(#s(ert--stats :selector (and t) :tests [#s(ert
  ert-run-tests((and t) (lambda (event-type &rest event-args) (cond ((
  ert-runner/run-tests-batch((and t))
  (let ((stats (ert-runner/run-tests-batch selector))) (kill-emacs (if
  ert-runner/run-tests-batch-and-exit((and t))
  (if ert-runner-verbose (ert-runner/run-tests-batch-and-exit ert-runn
  (let ((test-files (ert-runner--test-files tests)) (test-helper (f-ex
  ert-runner/run()
  apply(ert-runner/run nil)
  commander--handle-command(nil)
  commander-parse(nil)
  (if commander-parsing-done nil (commander-parse (or commander-args (
  eval-buffer(#<buffer  *load*> nil "/home/p
  load-with-code-conversion("/home/p/f.
  load("/home/p/f.el/.cask/27.0/elpa/er
  command-line-1(("-scriptload" "/home/p
  command-line()
  normal-top-level()

Test f-move-test/move-absolute-path condition:

    (file-error "Renaming" "Is a directory" "/home/p/f.el/test/playground/foo.txt" "/home/p/f.el/test/playground/bar")

FTest f-move-test/move-relative-path backtrace:

  rename-file("foo.txt" "bar" t)
  (if f--guard-paths (if (---truthy\? (let (needle) (let ((list f--gua
  f-move("foo.txt" "bar")
  (let ((default-directory f-test/playground-path)) (mapc (function (l
  (closure (t) nil (let ((default-directory f-test/playground-path)) (
  ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
  ert-run-test(#s(ert-test :name f-move-test/move-relative-path :docum
  ert-run-or-rerun-test(#s(ert--stats :selector (and t) :tests [#s(ert
  ert-run-tests((and t) (lambda (event-type &rest event-args) (cond ((
  ert-runner/run-tests-batch((and t))
  (let ((stats (ert-runner/run-tests-batch selector))) (kill-emacs (if
  ert-runner/run-tests-batch-and-exit((and t))
  (if ert-runner-verbose (ert-runner/run-tests-batch-and-exit ert-runn
  (let ((test-files (ert-runner--test-files tests)) (test-helper (f-ex
  ert-runner/run()
  apply(ert-runner/run nil)
  commander--handle-command(nil)
  commander-parse(nil)
  (if commander-parsing-done nil (commander-parse (or commander-args (
  eval-buffer(#<buffer  *load*> nil "/home/p
  load-with-code-conversion("/home/p/f.
  load("/home/p/f.el/.cask/27.0/elpa/er
  command-line-1(("-scriptload" "/home/p
  command-line()
  normal-top-level()

Test f-move-test/move-relative-path condition:

    (file-error "Renaming" "Is a directory" "/home/p/f.el/test/playground/foo.txt" "/home/p/f.el/test/playground/bar")

F........................................................................................

Ran 229 tests in 29.509 seconds
5 unexpected results:
   FAILED  f-copy-contents-test/copy-directory
   FAILED  f-copy-test/copy-absolute-dir-exists
   FAILED  f-copy-test/copy-relative-dir-exists
   FAILED  f-move-test/move-absolute-path
   FAILED  f-move-test/move-relative-path
Makefile:13: recipe for target 'unit' failed
make[1]: *** [unit] Error 1
make[1]: Leaving directory '/home/p/f.el'
Makefile:7: recipe for target 'test' failed
make: *** [test] Error 2

f-split doesn't handle tilde paths

It's considered an absolute path by the function underlying f-absolute?, and so f-split prepends a path separator.

(f-split "~/.zshrc") ;; => ("/" "~" ".zshrc")

Remaining file vs directory issues

A few things stand out as left over from #86 (and #89), but I'm not completely familiar with f.el and intended behaviour.

  1. I think additional file-name-as-directory calls in tests (added by #86) should be removed as part of #89.
  2. f-dirname/f-parent should probably return a trailing slash, and thus tests modifications in #89 should be reverted. This has knock-on effects for several other functions that could be quite tricky.
  3. Potentially f-filename should return a trailing slash for inputs with a trailing slash. It sounds odd to have a function called f-filename return a directory, but it seems intended to be equivalent to basename. This also has knock-on effects for other functions.

I haven't checked the full range of tests but neither of those PRs added many tests, whilst behaviour of underlying Emacs functions became more subtle and behaviour of f.el changed in some cases. I'm looking for @phst to add to the discussion, since they seem to know more about it than I do and were responsible for those PRs. #70 also seems relevant.

Loading f-shortdoc slows down the loading process

Contact Details

No response

Expected behavior

Loading f.el on Emacs 28+ shouldn't be slower than older versions

Actual behavior

Requiring the uncompiled "f-shortdoc" make loading "f.el" ~3 times slower.

Just using an newer version of Emacs makes startup a bit slower doesn't sound right.

f.el version

master

Emacs version

master

Relevant code or log output

With s, dash, shortdoc already loaded. f, f-short aren't.

(benchmark-progn (require 'f-shortdoc))
> Elapsed time: 0.001459s
(benchmark-progn (require 'f))
> Elapsed time: 0.000756s

No changes in v0.18.1?

Given

artemis ~/src/f-el % git diff v0.17.3..v0.18.1
diff --git a/f.el b/f.el
index 8d3223e..f2e077c 100644
--- a/f.el
+++ b/f.el
@@ -4,7 +4,7 @@

 ;; Author: Johan Andersson <[email protected]>
 ;; Maintainer: Johan Andersson <[email protected]>
-;; Version: 0.17.3
+;; Version: 0.18.1
 ;; Keywords: files, directories
 ;; URL: http://github.com/rejeep/f.el
 ;; Package-Requires: ((s "1.7.0") (dash "2.2.0"))

did you perhaps forget to merge in the development branch before tagging the new release? Thanks.

f-up misbehaving for top-level directories

There is a simple test for f-up:

(ert-deftest f-up-test/true ()
  (with-playground
   (should (equal f-test/playground-path (f-up (lambda (path) t))))))

This test seems to imply that dir and (f-up (lambda (path) t) dir) should always be equal, which seems reasonable. However, the current implementation of f-up doesn't have this invariant for top-level directories:

(mapcar
 (lambda (dir)
   (list dir (f-up (lambda (path) t) dir)))
 '("/usr/share" "/usr" "/"))
;; Result:
(("/usr/share" "/usr/share") ("/usr" "/") ("/" "/"))

This is version 20150113.24 of f.el on Emacs 25.0.50.1.

v0.18.0 tag

Hello,

Version 0.18.0 has not yet been released, but the f.el repository has a v0.18.0 tag. This is confusing Debian tooling which thinks that a new upstream version is available. I would really appreciate it if this false tag could be removed:

git tag -d v0.18.0
git push origin :refs/tags/v0.18.0

Thanks.

Sean

Version 1.18.1 or 0.18.1?

The new release is tagged 1.18.1, but in f.el the release is given as 0.18.1. Which is correct? Since the previous release was 0.17.3 I assume that the new one is 0.18.1 and the tag is incorrect, but please confirm. Thanks!

f-slash for non-existent directories

This is a terrific and useful package, thanks.

There are times when I need to manipulate directory names that do not (yet) exist. But f-slash, and thus f-full, do not append the slash in this case. I'm not sure whether f-slash should have the requirement of an existing directory. I think I prefer that it not, but I can see arguments both ways. However, if there is that requirement, I think it should be made clear in the documentation.

If the existence requirement is kept for f-slash, it might be a nice alternative to allow an optional argument to force the behavior:

(defun f-slash (path &optional if-not-exists)
  "Append slash to PATH unless one is already present.
A slash will not be appended for a non-existent directory path
unless IF-NOT-EXISTS is non-nil. Some functions, such as
 `call-process' requires there to be an ending slash."
  (if (or (f-dir? path) if-not-exists)
      (file-name-as-directory path)
    path))

This could be propagated to f-full (e.g., as-directory) which is the only function calling f-slash. I see that you need the requirement for f-full so that it can distinguish an arbitrary path as file or directory. However, it seems to me that that is where the requirement belongs rather than in f-slash, which by name just adds a slash. (UPDATED)

One could, of course, just call file-name-as-directory in this case, but we might as
well keep the advantage of a unified interface.

Make f-directories optionally ignore permission errors

Hi!

I constructed the following little helper function to help me fill up my projectile index just now:

(defun my/find-git-projects (dir)
  "Find all git projects under DIR."
  (mapcar #'f-dirname
          (f-directories "~/Documents/"
                         (lambda () (equal (f-filename dir) ".git"))
                         t)))

Unfortunately I get the following error:

f--collect-entries: Opening directory: Permission denied, c:/Users/mattias.bengtsson/AppData/Local/Application Data

Would it be possible to teach f-directories to optionally ignore directories it can't reach due to permissions instead of erroring out?

Add f-current-library

What about f-current-library which returns the file name of the currently loaded library?

I should cover the following three cases:

  • The file being byte compiled
  • The file being loaded
  • And the file being evaluated with eval-buffer.

An implementation of this is already contained in cask-cli.el.

New Release Request

Hi, thanks for the great package! Are you planning on making a new stable/versioned release soon? It'd be really nice to have a stable version assigned to the recent backwards incompatible changes.

f-join not working as expected

I am trying to join two path using f-join function.

(message "%s" (f-join "C:/Program Files (x86)/Microsoft Visual Studio/" "/Community/VC/Tools/MSVC/"))

Output

c:/Community/VC/Tools/MSVC/

Expected Output

C:/Program Files (x86)/Microsoft Visual Studio/Community/VC/Tools/MSVC/

Any idea? 😕

`f-join` does not behave like `expand-file-name`.

I beleaved that f-join behaves like expand-file-name (or concat if args are valid). However it does not currently:

(expand-file-name "dir/" "/path/to")                  ; => "/path/to/dir/"
(f-join "/path" "to" "dir/")                          ; => "/path/to/dir"
(file-name-as-directory (f-join "/path" "to" "dir/")) ; => "/path/to/dir/"

Sometimes this difference causes bugs. IMHO lisp functions should not depend on whether directory name ends slash or not, but in practice, for example,

(setq auto-save-list-file-prefix (f-join "~" ".emacs.d" "auto-save-list/"))

will cause unpleasant result. I feel the name auto-save-list-file-prefix is fair and the "bug" is due to the difference between expected behavior from the name f-join and its actual behavior.

It is easy to fix but the change breaks adjointness (relation nearly inverse) of f-join and f-split. How do you think of it?

If you agree, I'll send PR. If not, please declare that and note this case in doc-string and test.

Perhaps tag a release?

The ebal package depends on the f-swap-ext function that isn't in any released version of f. That means it can't depend on anything but a melpa version.

Optimization for directory-files

Hi there,

In this interesting discussion with Alexander Miller, he mentioned that directory-files is faster when called in a temp buffer. This quick test seems to show that it is indeed:

#+BEGIN_SRC elisp
  (defun f--collect-entries--tb (path recursive)
    (with-temp-buffer
      (let (result
            (entries
             (-reject
              (lambda (file)
                (or
                 (equal (f-filename file) ".")
                 (equal (f-filename file) "..")))
              (directory-files path t))))
        (cond (recursive
               (-map
                (lambda (entry)
                  (if (f-file? entry)
                      (setq result (cons entry result))
                    (when (f-directory? entry)
                      (setq result (cons entry result))
                      (setq result (append result (f--collect-entries entry recursive))))))
                entries))
              (t (setq result entries)))
        result)))


  (list (cons "without temp buffer"
              (progn
                (garbage-collect)
                (benchmark-run-compiled 100
                  (f--collect-entries "~/.emacs.d" nil))))
        (cons "with temp buffer"
              (progn
                (garbage-collect)
                (benchmark-run-compiled 100
                  (f--collect-entries--tb "~/.emacs.d" nil)))))
#+END_SRC

#+RESULTS:
| without temp buffer | 0.31999160200000004 | 0 | 0.0 |
| with temp buffer    |         0.191897104 | 0 | 0.0 |

I thought I should let you know in so that it could be added to f--collect-entries. Seems like a nice, free optimization. :)

Thanks for your work on f.el!

f-entries can't handle unreadable directories

If the directory tree being traversed by f-entries has any unreadable directories,
f-entries still tries to recurse into it and throws an error. Here ~/.cache/dconf is
not readable by the emacs process, and f-entries returns no results:

ELISP> (f-entries "/home/work/.cache/" nil t)
*** Eval error ***  Opening directory: Permission denied, /home/work/.cache/dconf

The expected result should be that unreadable directories are in the results, but no recursion is performed on them.

Redundant buffer-substring-no-properties for f-read-bytes?

As I was studying your library, I was wondering if in this case buffer-substring-no-properties is redundant for f-read-bytes?

(defun f-read-bytes (path)
"Read binary data from PATH.
Return the binary data as unibyte string."
(with-temp-buffer
(set-buffer-multibyte nil)
(setq buffer-file-coding-system 'binary)
(insert-file-contents-literally path)
(buffer-substring-no-properties (point-min) (point-max))))

Since insert-file-contents-literally does not run find-file-hook (nor format decoding, character code conversion, automatic uncompression, and so on), wouldn't buffer-string suffice?

In that way, buffer-string would make it a little simpler?

f-uniquify-alist performance issue on files vs directories

Great library guys, real help.

So I've been using f-uniquify-alist along with projectile which is cool. I just noticed in a big project where there are 642 files and 140 directories, said function hangs when I run it with projectile-current-project-dirs and weirdly it doesn't hang when it is run with projectile-current-project-files. This is sort of weird when there are more files than there are directories and yet it chokes.

After some investigation, given a minimal test path list of (list "a/b/c/d/" "a/B/c/d/"); this creates an infinite loop with (s-chop-prefix "d" "a/b/c/d/") instead of the correct (s-chop-prefix "d/" "a/b/c/d/").

Please consider keeping changelog in its own file

Hi,

I'd be grateful if you'd consider keeping the changelog in its own file (e.g. CHANGELOG.md). That way, the Debian packaging of f.el can just install that file. At present, I have to manually extract the changelog data on each release.

Thanks!

f not in melpa through emacs package manager; but in "https://melpa.org/#/" website. it's so surprise

eyedropper 20150509.1345 available melpa Pick foreground and background colors at cursor or pointer.
eyuml 20141028.1527 available melpa Write textual uml diagram from emacs using yuml.me
ez-query-replace 20140810.517 available melpa a smarter context-sensitive query-replace that can be reapplied
f90-interface-b... 1.1 available gnu Parse and browse f90 interfaces
fabric 20141024.322 available melpa Launch Fabric using Emacs
face-remap+ 20150104.1358 available melpa Extensions to standard library face-remap.el'. facemenu+ 20150816.1953 available melpa Extensions tofacemenu.el'.
faces+ 20150104.1400 available melpa Extensions to `faces.el'.

Thoughts on accepting a PR for f-contract

You have f-expand. What about supporting f-contract?

(f-contract "/home/wpcarro/file.txt") ;; => "~/file.txt"

I often need this to write predicates that work across my different machines that return different values for ~. I'm happy to create a PR if you're open to the idea.

If this already exists, and I've missed the function, please let me know!

[Help]: Faster way to search for directories recursively

Contact Details

@jingxlim

New feature

Hi, I wanted to preface this by saying that this is neither a feature request nor a bug report, and more like a cry for help.

I wanted my little script to help me find directories that contain .org files. I also wanted these directories to not be at any point, hidden. To this end, I am glad that I found f.el, which did all the heavy-lifting.

Here are the few lines of code I wrote. Bear in mind that the following are literally the first few lines of Emacs Lisp I have written, ever, which is why I'm hoping to get some feedback. I also never took a course or went through a beginners tutorial on Emacs Lisp; and instead just decided to dive right into it just by looking particular things up. It's probably not the most Lisp-y (if there's even such a thing) and very verbose, but please bear with me!

(defun is-dotstring (str)
  (integerp(string-match-p "^\\.\\w.*$" str))
  )

(defun path-has-dotstring (path)
  (consp (member t (mapcar #'is-dotstring (f-split path))))
  )

(defun dir-has-filetype (path filetype)
  (consp (f--files path (equal (f-ext it) filetype)))
  )

(f-directories root_directory (lambda (dir) (and (not (path-has-dotstring dir)) (dir-has-filetype dir "org"))) t)

So for the root_directory that I specified, this piece of code took somewhere from 1-2 minutes to run. Because I also hope to run this at the startup of Emacs, this speed won't do.

On the other hand, something like the Linux tool find achieved the same thing in less than 5 seconds.

find [root_directory] -name '*.org' -not -path '*/.*' -printf '%h\n' | sort -u

Of course, I am not claiming that I wrote them the same way, so differences in performance is expected.

However, I do want to do this in Emacs, so I'm wondering if there are any ways I could improve on it, using f.el or otherwise (e.g. piping in the results from find). In the case of f-directories, I understand that every directory is visited recursively, even if it is many layers deep into a hidden directory (e.g. .git). Perhaps one way is to write the program in a way that prevents this from happening.

Any help is greatly appreciated! Thanks!

Why this new feature

f.el is great! I just need help using it!

Implementation ideas and additional thoughts

It could be implemented doing foo, bar, and baz

f-parent is inconsistent wrt ending slash

(f-parent "/foo/bar/baz") ;; => "/foo/bar"
(f-parent "foo/bar/baz")  ;; => "foo/bar/"

I find the kind of "reverse symmetry" pretty funny :D

Anyway, this also breaks f-common-parent. I tried wrapping it with f-slash but that doesn't append the final slash in some cases, which leaves me puzzled as to what is its purpose then?

wait-timeout for f--collecting-entries

Hi,

I found out that f--collecting-entries function takes quite a lot of time when it recursively collects entries (where a directory has many entries). I wanted to use wait-timeout to wrap f--collecting-entries but it doesn't work with the current implementation because f--collecting-entries never wait for an input.

My current work-around is to insert (sit-for 0.000001) at https://github.com/rejeep/f.el/blob/master/f.el#L425 . I'm wondering whether there is a better solution for my problem. Any suggestion is welcome.

f-up return value

Currently f-up returns the file system root, if the given predicate never returns non-nil.

Hence, the caller can't use the truthyness of the return value to determine whether the predicate ever matched. Instead, they need to check the return value with f-root? and with the predicate (in case that the file system root could have matched).

That is, instead of (when (f-up #'my-predicate directory) …), you need to use (let ((ancestor (f-up #'my-predicate directory))) (when (or (not (f-root? ancestor)) (my-predicate ancestor) …).

I think f-up should be deprecated, and replaced with a function f-traverse-upwards that behaves the same, but returns nil, if the predicate never returned non-nil.

f requires dash 2.2 but that does not yet exist

Hi

Maybe I am misreading things, but I just noticed that Dash on elpa is at version: 2.12.0. However, f on melpa "Requires: dash-2.2.0".

I noticed this when running emacs -Q and package-initialize

Unable to activate package ‘f’.
Required package ‘dash-2.2.0’ is unavailable

When I run emacs (without the -Q) this does not seem to be a problem (and that is confusing).

Unintuitive f-join behavior

ELISP> (f-join "a" "/b")
"../../../../b"
ELISP> (cd "~")
"/home/sindikat/"
ELISP> (f-join "a" "/b")
"../../b"

f-join behaves strange when meets an argument starting with slash, depending on a current directory in Emacs. In Python, for example, os.path.join simply discards all previous arguments when meets an argument starting with slash. Do you think it is better to make f-join behave like Python's?

`f-copy` to copy all files

Hi,

How could one simulate the following cp action:
cp -r ~/path/to/source/ ~/path/to/target/

The following syntax does not have the same effect:
(f-copy "~/path/to/source/" "~/path/to/target/"

As it copies source dir into target dir.

Thank you so much for f.el.

Posix stat metadata

Would it be possible to add something like f-stat, which would return Posix stat metadata about a given path?

Right now one would need to have a system call to fecth that metadata.

(f-stat "file.txt")
;; device  16777222
;; inode   4080486
;; mode    33188
;; nlink   1
;; uid     501
;; gid     20
;; rdev    0
;; size    1500520
;; atime   1451758319
;; mtime   1423242348
;; ctime   1451831422
;; blksize 4096
;; blocks  2936
;; link nil

I find f.el extremely useful. Thank you so much.

Add f-split

It would be nice to add an f-split function that does the inverse of f-join, so (f-split "foo/bar/baz.txt") would return ("foo" "bar" "baz.txt").

I've looked through the docs, but I don't think f.el currently offers this functionality.

f-join is trying to open a tramp connection when it shouldn't

(f-join (f-root) "C:\\Users\\61169.html")

Surprisingly, this gives me the following when executed on linux:

ssh: Could not resolve hostname c: Name or service not known

and

Tramp: Waiting for prompts from remote shell...failed
Tramp: Opening connection for C using scp...failed
tramp-file-name-handler: Tramp failed to connect.  If this happens repeatedly, try
    ‘M-x tramp-cleanup-this-connection’

I understand that I'm feeding f-join with garbage but I think it should nevertheless not attempt to open connections.

Clarify f-ext documentation

Currently, f-ext is described as follows:

Return the file extension of PATH.

However, it uses file-name-extension, which strips version numbers and backup suffixes. It would be nice if that fact could be mentioned as well. I fell for that today, because

(f-files "/some/path"
         (lambda (x)
           (f-ext? x "md")))

will also return all backup files (ending in "md~")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.