GithubHelp home page GithubHelp logo

supitsdu / clipper Goto Github PK

View Code? Open in Web Editor NEW
3.0 2.0 3.0 178 KB

Seamlessly copy file contents to clipboard from command line. Lightweight, cross-platform tool for instant text transfers.

License: MIT License

Go 64.85% Makefile 7.78% Shell 27.38%
automation cli clipboard command-line-tool copy-to-clipboard developer-tools go utility

clipper's Introduction

Hi!

I'm Eduardo, an aspiring software engineer with 8 years of coding experience (as a hobby). I'm pursuing a Bachelor's degree in Software Engineering to further my skills and knowledge.

Passionate About

  • Coding: Always eager to learn and apply new programming concepts.
  • Open Source: Contributing to projects and collaborating with others.
  • Problem Solving: Thriving on challenges and finding creative solutions.

Tech Stack

  • Languages: JavaScript (Advanced), Go (Learning), Rust (Learning)
  • Tools: GitHub, Notion
  • Interests: Web development, Linux utilities, back-end infrastructure

Featured Projects

Learning & Exploring

  • Deepening my JavaScript expertise
  • Mastering the Go programming language
  • Exploring the power of Rust

I'm open to collaborating on:

  • Open-source projects related to web development, Linux utilities, or back-end infrastructure
  • JavaScript libraries or frameworks

clipper's People

Contributors

ccoveille avatar karimalzalek avatar supitsdu avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

clipper's Issues

Explore Concurrency (goroutines and channels) for Copying from Multiple Files

When copying content from multiple files, clipper currently processes them sequentially. This might be inefficient, especially when dealing with a large number of files.

We should investigate the use of concurrency with goroutines and channels to parallelize the reading of content from multiple files. This could significantly speed up the copying process in such scenarios.

See:

Tasks:

  1. Design and implement a concurrent solution using goroutines and channels to read content from multiple files simultaneously.
  2. Consider potential synchronization issues and error handling in a concurrent environment.
  3. Benchmark the performance improvement when copying content from multiple files.
  4. Update documentation to explain the use of concurrency.

Improve Performance with Buffered I/O (bufio) for Large File Handling

Currently, clipper reads and writes file content directly using standard I/O operations. When dealing with large files, this can lead to suboptimal performance due to the overhead of frequent system calls.

We could introduce buffered I/O (e.g.: bufio) for file operations. This involves using a buffer to read and write data in larger chunks, reducing the number of system calls and potentially significantly improving performance, especially when working with large files.

Tasks:

  1. Replace direct file reads (os.ReadFile) and writes (io.ReadAll) with buffered I/O operations. e.g.: using bufio.NewReader and bufio.NewWriter.
  2. Benchmark the performance improvement when copying content from large files to the clipboard.
  3. Update documentation to reflect the use of buffered I/O.

Refactor `options.Config` to Remove Pointer for `DirectText` (Improving Usability and Testing)

The options.Config struct currently uses a pointer to a string (*string) for the DirectText field. This design choice was initially made to accommodate the return type of flag.String in the ParseFlags() function. However, it has led to increased complexity and challenges in testing and usage due to the need for pointer dereferencing.

Reasoning:

As noted in the PR review, using a pointer for DirectText provided minimal memory optimization benefits and introduced unnecessary complications. Removing the pointer simplifies the code and avoids potential nil pointer errors during testing and subsequent usage.

Proposed Changes:

  1. Remove Pointer: Change the type of the DirectText field in options.Config from *string to string.
  2. Update ParseFlags(): Modify the ParseFlags() function to assign the value returned by flag.String directly to the DirectText field (which is now a string).
  3. Update clipper Package: Ensure that any references to config.DirectText in the clipper package are updated to reflect the change in type.
  4. Update Tests: Adjust unit tests in the clipper_test package to account for the new type of the DirectText field.

Expected Benefits:

  • Simplified Code: Removing the pointer from DirectText will make the code simpler and easier to understand.
  • Improved Usability: Eliminate the need for pointer dereferencing when accessing config.DirectText.
  • Easier Testing: Avoid potential nil pointer issues during testing.
  • Maintain Performance: The performance impact of using a string instead of *string is expected to be negligible in this context.

Originally posted by @ccoVeille in #29 (comment)

Enhance Clipper with Folder Copying, File Type/Extension Filtering, and Size Filtering (Dependent on Performance Enhancements)

Currently, Clipper only supports copying text content from files or standard input. This enhancement aims to significantly expand the tool's functionality by enabling it to copy entire files located within a specified folder. Additionally, it will provide filtering options based on file type/extension and size, giving users more granular control over what gets copied.

Prerequisites:

  • Performance Enhancements: This feature relies on performance improvements, specifically, using goroutines and concurrency features for parallel file processing (Issue #23), and buffered file reading. These optimizations are essential to ensure efficient and responsive handling of potentially large numbers of files.

Proposed Features:

  1. Folder Copying: Add a new flag (e.g., -d or --directory) to specify a folder path. Clipper will then copy all files within that folder to the clipboard (or a designated output location).
  2. File Type/Extension Filtering: Implement flags or options to filter files based on their type or extension. For example:
    • -t text or --type text: Copy only text files.
    • -e jpg,png or --extension jpg,png: Copy only JPG and PNG images.
  3. Size Filtering: Add options to filter files based on minimum and maximum size:
    • -min 10KB: Copy only files larger than or equal to 10 kilobytes.
    • -max 1MB: Copy only files smaller than or equal to 1 megabyte.

Additional Considerations:

  • User Interface: Determine the best way to present these new options to the user (e.g., additional flags, subcommands).
  • Clipboard Size Limitations:
    • Windows: No theoretical limit, but practical constraints due to available memory.
    • macOS: No specific limit documented, but large amounts of data may impact performance.
    • Linux (X11): Clipboard managers may have configurable size limits. Investigate using the xclip utility or other clipboard libraries to handle potentially large amounts of file data.
  • Error Handling: Implement robust error handling for invalid folder paths, incorrect filter values, out-of-memory errors, etc.
  • Recursive Copying: Investigate the possibility of adding an option for recursive copying (copying files from subfolders as well).

Reduce complexity when parsing content

The complexity of the code was increased with #13 by the multiple branching if

The parsing of the content could be moved out the main with something like this

contentStr, err := parseContent(flag)
if err != nil {
fmt.Println
os.Exitt(1)
}

// …

func parseContent(flag) string, error {
   if directText != {
      return *directText
   }

   // …
}

Originally posted by @ccoVeille in #13 (comment)

Fix Unexpected Newline in Output when Copying Empty Files

During a code review of Pull Request #29, it was discovered that when ParseContent is used to copy content from an empty file, the output contains an unexpected newline character (\n) instead of an empty string. This behavior was observed in the following scenario:

  • The readers slice passed to ParseContent contains a FileContentReader where the FilePath points to an empty file.
  • The function returns a string containing only a newline character ("\n") instead of an empty string ("").

Expected Behavior:

When copying content from an empty file, ParseContent should return an empty string to accurately reflect the lack of content in the file.

Proposed Fix:

Add a check within the loop in ParseContent to ensure that the content read from each reader is not empty before appending a newline character and writing it to the strings.Builder.

Additional Notes:

  • Review the unit tests for ParseContent to ensure they cover the case of empty file input.
  • Consider adding a test specifically for this scenario to prevent regressions in the future.

Originally posted by @ccoVeille in #29 (comment)

Refactor Package Name for Clarity (from main to clipper or clipboardtool)

The current package name (main) is generic and doesn't reflect the purpose of clipper. Renaming it to something more descriptive, like clipper or clipboardtool, would enhance code organization and make the project's structure more intuitive.

Tasks:

  1. Rename the main package to either clipper or clipboardtool.
  2. Update any references to the package in import statements and documentation.

Improve Version Management to Distinguish Between Development and Production Builds

Currently, Clipper relies solely on Git tags to determine the version displayed using the -v flag. While this works well for production builds, it's not ideal for development environments where the codebase might not always be tagged.

This enhancement aims to provide a more informative and user-friendly approach to version management.

Proposed Changes:

  1. Development Version:
    • Introduce a default "dev" version string (e.g., "v0.0.0-dev") that is displayed when the code is run directly without being built (e.g., go run main.go).
    • Consider appending a timestamp or commit hash to the "dev" version for precise track of development builds.
  2. Build Version:
    • During the build process, continue using Git tags to determine the version if available.
    • If no tag is found, use a fallback version string (e.g., "v0.0.0-unreleased") to indicate that the build is not associated with a specific release.
  3. Display Logic:
    • Refactor the code to conditionally display the appropriate version based on whether the tool is running from a built binary or in development mode.

Goals:

  • Clarity: Provide clear and distinct version information to users, differentiating between development and production builds.
  • Flexibility: Allow developers to easily identify the specific version of the code they are running during development.
  • Maintainability: Make version management more robust and adaptable to different workflows.

Additional Considerations:

  • Configuration: Explore options to allow users to customize the development version string or override the default behavior.
  • Version Format: Decide on a standardized format for development versions (e.g., vX.Y.Z-dev+timestamp) to ensure consistency.

Improve Informativeness of Success and Error Messages

The current messages displayed by clipper are somewhat basic. We can improve the user experience by making the messages more informative.

For example:

  • Success: Instead of "Clipboard updated successfully", specify the amount of data copied (e.g., "Copied 1024 bytes to clipboard").
  • Error: Provide more context about the cause of the error (e.g., "Error reading file 'example.txt': Permission denied").

Tasks:

  1. Review and revise the messages displayed in the main function.
  2. Consider using different colors or formatting to distinguish between success and error messages.

Enhance User Experience with Visual Feedback for Long Operations

When clipper is reading large files or copying extensive content to the clipboard, there's currently no visual feedback to the user. This can lead to uncertainty about whether the operation is in progress.

We should add visual feedback, such as a spinner or progress bar, to indicate that a long operation is ongoing and to provide an estimate of its completion time.

Tasks:

  1. Choose a suitable visual feedback mechanism (spinner, progress bar, etc.).
  2. Implement the mechanism to display during file reading and clipboard copying operations that exceed a certain threshold (e.g., size or duration).
  3. Consider customization options for the visual feedback (e.g., allowing the user to disable it).

Add golangci-lint to project

I can help you to add golangci-lint to your project.

Many of the issues I raised would have been detected.

Using golangci-lint helped me a lot in my understanding of Go

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.