├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── NAMESPACE ├── R ├── add_to_rprofile.R ├── check_mark.R ├── doc_package.R ├── function.R ├── regex_rules.R ├── rerun.R └── zzz.R ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── data-raw ├── devtools_tricks.R ├── idee.cpp ├── langage.R └── test.R ├── fcuk.Rproj ├── img └── fcuk-hex-thinkr.png ├── man ├── add_fcuk_to_rprofile.Rd ├── catch_error.Rd ├── error_analysis.Rd ├── error_correction_propostion.Rd ├── fcuk-package.Rd ├── get_all_objets_from_r.Rd ├── get_last.Rd ├── init_error_tracker.Rd ├── plus-.fcuk.Rd └── remove_error_tracker.Rd ├── tests ├── testthat.R └── testthat │ ├── test-catch_error.R │ ├── test-erreur_correction_propostion.R │ ├── test-error_analysis.R │ ├── test-get_all_objets_from_r.R │ └── test-regex.R └── vignettes ├── fcuk.R └── fcuk.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CODE_OF_CONDUCT\.md$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^data-raw$ 5 | ^\.travis\.yml$ 6 | ^codecov\.yml$ 7 | img 8 | ^_pkgdown\.yml$ 9 | ^docs$ 10 | ^pkgdown$ 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | # Example code in package build process 8 | *-Ex.R 9 | # Output files from R CMD build 10 | /*.tar.gz 11 | # Output files from R CMD check 12 | /*.Rcheck/ 13 | # RStudio files 14 | .Rproj.user/ 15 | # produced vignettes 16 | vignettes/*.html 17 | vignettes/*.pdf 18 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 19 | .httr-oauth 20 | # knitr and R markdown default cache directories 21 | /*_cache/ 22 | /cache/ 23 | # Temporary files created by R markdown 24 | *.utf8.md 25 | *.knit.md 26 | .Rproj.user 27 | # Pkgdown 28 | docs/* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | language: R 3 | sudo: false 4 | cache: packages 5 | 6 | r_github_packages: 7 | - ThinkR-open/fcuk # pre-install to avoid vignette package errors 8 | 9 | # build matrix; turn on vdiffr only on r release 10 | matrix: 11 | include: 12 | - r: devel 13 | - r: release 14 | env: VDIFFR_RUN_TESTS=true 15 | before_cache: 16 | - Rscript -e 'remotes::install_cran("pkgdown")' 17 | - Rscript -e 'remotes::install_github("ThinkR-open/thinkrtemplate")' 18 | deploy: 19 | provider: pages 20 | skip-cleanup: true 21 | github-token: $GITHUB_PAT 22 | keep-history: true 23 | local-dir: docs 24 | on: 25 | branch: master 26 | skip_cleanup: true 27 | - r: oldrel 28 | 29 | before_install: 30 | - Rscript -e 'update.packages(ask = FALSE)' 31 | 32 | after_success: 33 | - Rscript -e 'devtools::test()' 34 | - Rscript -e 'covr::codecov()' 35 | - Rscript -e 'pkgdown::build_site()' 36 | 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http://contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Type: Package 2 | Package: fcuk 3 | Title: The Ultimate Helper for Clumsy Fingers 4 | Version: 0.1.3.1 5 | Date: 2017-07-05 6 | Author: Vincent Guyader 7 | Authors@R: c(person('Vincent', 'Guyader', email = 'vincent@thinkr.fr', role = c('cre', 'aut'), comment = c(ORCID = "0000-0003-0671-9270")), 8 | person(given = "ThinkR", role = "cph")) 9 | Description: Automatically suggests a correction when a typo occurs. 10 | License: GPL-3 11 | URL: https://thinkr-open.github.io/fcuk/, https://github.com/ThinkR-open/fcuk 12 | BugReports: https://github.com/ThinkR-open/fcuk/issues 13 | Imports: 14 | crayon, 15 | magrittr, 16 | purrr, 17 | stringdist, 18 | tibble, 19 | rstudioapi, 20 | clisymbols, 21 | stringr 22 | Suggests: 23 | knitr, 24 | rmarkdown, 25 | testthat, 26 | covr, 27 | pkgdown 28 | VignetteBuilder: knitr 29 | ByteCompile: true 30 | Encoding: UTF-8 31 | LazyData: true 32 | RoxygenNote: 6.1.1 33 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("+",fcuk) 4 | S3method(print,blank) 5 | export(.) 6 | export(add_fcuk_to_rprofile) 7 | export(catch_error) 8 | export(error_analysis) 9 | export(error_correction_propostion) 10 | export(get_all_objets_from_r) 11 | export(get_last) 12 | export(init_error_tracker) 13 | export(remove_error_tracker) 14 | import(stringdist) 15 | importFrom(crayon,italic) 16 | importFrom(crayon,white) 17 | importFrom(magrittr,"%>%") 18 | importFrom(purrr,flatten_chr) 19 | importFrom(purrr,map) 20 | importFrom(purrr,map_chr) 21 | importFrom(rstudioapi,sendToConsole) 22 | importFrom(stringr,str_subset) 23 | importFrom(stringr,str_trim) 24 | importFrom(tibble,tribble) 25 | importFrom(utils,installed.packages) 26 | -------------------------------------------------------------------------------- /R/add_to_rprofile.R: -------------------------------------------------------------------------------- 1 | #' Add library(fcuk) to the .Rprofile file 2 | #' 3 | #' After calling this function, fcuk will be launched everytime you launch your 4 | #' current R project (or any project if you use option \code{global = TRUE}). 5 | #' 6 | #' @param global Whether to add it to the global .Rprofile (\code{TRUE}) or just 7 | #' to the .Rprofile file of your current project (\code{FALSE}, the default). 8 | #' @importFrom stringr str_trim str_subset 9 | #' @importFrom magrittr %>% 10 | #' @export 11 | #' @examples 12 | #' fcuk::add_fcuk_to_rprofile() 13 | add_fcuk_to_rprofile <- function(global = TRUE) { 14 | 15 | file <- `if`(global, "~/.Rprofile", ".Rprofile") 16 | 17 | if (file.exists(file)) { 18 | rl <- readLines(file) %>% str_trim() %>% str_subset("^[^#]") 19 | 20 | already_there <- any(grepl("(fcuk)", rl, fixed = TRUE)) 21 | if (already_there) { 22 | enod("fcuk was already in " , file) 23 | return(invisible(NULL))} 24 | } 25 | 26 | to_add <- "\nif (interactive()) {\n suppressMessages(require(fcuk))\n}\n" 27 | cat(to_add, file = file, append = TRUE) 28 | done("Adding fcuk to ",file) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /R/check_mark.R: -------------------------------------------------------------------------------- 1 | # from usethis https://github.com/r-lib/usethis 2 | cat_line <- function(...) { 3 | cat(..., "\n", sep = "") 4 | } 5 | 6 | bullet <- function(lines, bullet) { 7 | lines <- paste0(bullet, " ", lines) 8 | cat_line(lines) 9 | } 10 | 11 | done <- function(...) { 12 | bullet(paste0(...), bullet = crayon::green(clisymbols::symbol$tick)) 13 | } 14 | enod <- function(...) { 15 | bullet(paste0(...), bullet = crayon::red(clisymbols::symbol$warning)) 16 | } -------------------------------------------------------------------------------- /R/doc_package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | # The following block is used by usethis to automatically manage 5 | # roxygen namespace tags. Modify with care! 6 | ## usethis namespace: start 7 | ## usethis namespace: end 8 | NULL -------------------------------------------------------------------------------- /R/function.R: -------------------------------------------------------------------------------- 1 | #' Extract the name of all objects loaded in the R environments 2 | #' 3 | #' Fetch the name of all objects loaded in the environments (functions, values, data...) 4 | #' 5 | #' @return a list with the names of all objects contained in the environments 6 | #' @export 7 | #' @importFrom purrr map flatten_chr 8 | #' @importFrom utils installed.packages 9 | #' @importFrom magrittr %>% 10 | #' @examples 11 | #' get_all_objets_from_r() 12 | get_all_objets_from_r <- function() { 13 | search() %>% 14 | map(ls,all.names = TRUE) %>% 15 | flatten_chr() %>% c(installed.packages() %>% rownames()) 16 | } 17 | 18 | #' Find closest object names 19 | #' 20 | #' Analyse a typo and suggests the two closest names. 21 | #' 22 | #' @param asked_objet the R name producing an error 23 | #' @param method Method for distance calculation. The default is "jaccard", see \link[stringdist]{stringdist-metrics}. 24 | #' @param n number of corrections to suggest. 25 | #' @return a character vector with the closest neighbors 26 | #' @export 27 | #' @import stringdist 28 | #' @examples 29 | #' error_correction_propostion("iri") 30 | 31 | error_correction_propostion <- function(asked_objet, method = "jaccard",n=2) { 32 | candidats <- get_all_objets_from_r() 33 | candidats[order(stringdist(tolower(asked_objet), tolower(candidats), method = method))][seq_len(n)] 34 | } 35 | 36 | 37 | 38 | 39 | #' Error Analysis 40 | #' 41 | #' @param asked_objet the name to analyse 42 | #' @param n number of names to suggest 43 | #' 44 | #' @export 45 | #' @examples 46 | #' fcuk::error_analysis() #last error is analysed 47 | #' fcuk::error_analysis("view") 48 | #' fcuk::error_analysis("iri") 49 | error_analysis <- function(asked_objet = catch_error(),n=2) { 50 | # browser() 51 | if (length(asked_objet)>0 && !is.na(asked_objet)) { 52 | # message(gettext("You ask :"), deparse(asked_objet), "\n") 53 | cat( 54 | gettext("Did you mean :"), 55 | out <- paste( 56 | corr <- error_correction_propostion(as.character(asked_objet)[1],n=n), 57 | collapse = gettext(" or ") 58 | ) 59 | , 60 | "?\n" 61 | ) 62 | 63 | init_rerun(corr,geterrmessage(),asked_objet) 64 | 65 | invisible(out) 66 | } 67 | } 68 | 69 | 70 | #' Capture and parse an error message. 71 | #' 72 | #' @param sentence an error message to parse 73 | #' @importFrom purrr map_chr 74 | #' @export 75 | #' @examples 76 | #' catch_error() 77 | #' catch_error("Error: object 'iri' not found\n") 78 | #' catch_error("Error: object 'view' not found\n") 79 | #' 80 | #' 81 | catch_error <- function(sentence = geterrmessage()) { 82 | regex_rules()$regex %>% 83 | map_chr(~sub(.x,"\\1",sentence)) %>% 84 | # unname() %>% 85 | .[. != sentence] 86 | } 87 | 88 | #' Init error tracker 89 | #' 90 | #' After lauching this function, every error message will be analysed. 91 | #' This function is called when loading the package. 92 | #' 93 | #' @export 94 | #' @examples 95 | #' getOption("error") 96 | #' fcuk::init_error_tracker() 97 | #' getOption("error") 98 | init_error_tracker <- function(){ 99 | 100 | options("old_error" = getOption("error")) 101 | options( error = function(...){ 102 | fcuk::error_analysis() 103 | # .rs.breakOnError(TRUE) 104 | 105 | } ) 106 | } 107 | 108 | 109 | 110 | #' Remove error tracker 111 | #' 112 | #' After lauching this function, the errors will no longer be analysed. 113 | #' 114 | #' @export 115 | #' @examples 116 | #' getOption("error") 117 | #' fcuk::remove_error_tracker() 118 | #' getOption("error") 119 | remove_error_tracker <- function() { 120 | options("error" = getOption("old_error")) 121 | } 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /R/regex_rules.R: -------------------------------------------------------------------------------- 1 | 2 | #' @noRd 3 | #' @importFrom tibble tribble 4 | regex_rules <- function(){ 5 | res <- tribble( ~error,~regex, 6 | "Error in sl() : \"sl\" fonksiyonu bulunamadi\n" ,".*\"(.*)\" fonksiyonu bulunamadi\n", 7 | "Error in sl() : could not find function \"sl\"\n" , ".*could not find function \"(.*)\"\n", 8 | "Error in sl() : fann ikkje funksjonen \u00ABsl\u00BB\n" , ".*fann ikkje funksjonen \u00AB(.*)\u00BB\n", 9 | "Error in sl() : impossible de trouver la fonction \"sl\"\n" , ".*impossible de trouver la fonction \"(.*)\"\n", 10 | "Error in sl() : konnte Funktion \"sl\" nicht finden\n" , ".*konnte Funktion \"(.*)\" nicht finden\n", 11 | "Error in sl() : n\u00E3o foi poss\u00EDvel encontrar a fun\u00E7\u00E3o \"sl\"\n" , ".*n\u00E3o foi poss\u00EDvel encontrar a fun\u00E7\u00E3o \"(.*)\"\n", 12 | "Error in sl() : nie udalo sie znalezc funkcji 'sl'\n" , ".*nie udalo sie znalezc funkcji '(.*)'\n", 13 | "Error in sl() : no se pudo encontrar la funci\u00F3n \"sl\"\n" , ".*no se pudo encontrar la funci\u00F3n \"(.*)\"\n", 14 | "Error in sl() : non trovo la funzione \"sl\"\n" , ".*non trovo la funzione \"(.*)\"\n", 15 | "Error in try(iri) : 'iri' nesnesi bulunamadi\n" , ".*'(.*)' nesnesi bulunamadi.*", 16 | "Error in try(iri) : fann ikkje objektet \u00ABiri\u00BB\n" , ".*fann ikkje objektet \u00AB(.*)\u00BB.*", 17 | "Error in try(iri) : nie znaleziono obiektu 'iri'\n" , ".*nie znaleziono obiektu '(.*)'.*", 18 | "Error in try(iri) : object 'iri' not found\n" , ".*'(.*)' not found.*", 19 | "Error in try(iri) : object \u0091iri\u0092 not found\n" , ".*\u0091(.*)\u0092 not found.*", 20 | "Error in try(iri) : objekt 'iri' blev ikke fundet\n" , ".*'(.*)' blev ikke fundet.*", 21 | "Error in try(iri) : Objekt 'iri' nicht gefunden\n" , ".*'(.*)' nicht gefunden.*", 22 | "Error in try(iri) : objet 'iri' introuvable\n" , ".*'(.*)' introuvable.*", 23 | "Error in try(iri) : objeto 'iri' n\u00E3o encontrado\n" , ".*'(.*)' n\u00E3o encontrado.*", 24 | "Error in try(iri) : objeto 'iri' no encontrado\n" , ".*'(.*)' no encontrado.*", 25 | "Error in try(iri) : oggetto \"iri\" non trovato\n" , ".*\"(.*)\" non trovato.*", 26 | "Error in library(dplir) :" , "Error in library\\(\"(.*)\"\\) :.*", 27 | "Error in library(dplir) :" , "Error in library\\('(.*)'\\) :.*", 28 | "Error in library(dplir) :" , "Error in library\\((.*)\\) :.*" 29 | ) 30 | 31 | 32 | res 33 | } 34 | -------------------------------------------------------------------------------- /R/rerun.R: -------------------------------------------------------------------------------- 1 | init_rerun <- function(...){ 2 | dots <- list(...) 3 | options(fcuk=dots) 4 | } 5 | 6 | #' @export 7 | . <- structure("", class= "fcuk") 8 | 9 | 10 | #' Rerun with correcyion 11 | #' 12 | #' @param x blank object of class fcuk 13 | #' @param y an integer corresponding to the position of the proposal to be reused 14 | #' 15 | #' @export 16 | #' @importFrom rstudioapi sendToConsole 17 | #' @importFrom crayon white italic 18 | #' @examples 19 | #' \dontrun{ 20 | #' view(iris)# error 21 | #' .+1 # return View(iris) 22 | #' 23 | #' } 24 | #' 25 | #' 26 | `+.fcuk` <- function(x, y){ 27 | 28 | # message("x=",x) 29 | # message("y=",y) 30 | # browser() 31 | # print(get_last(y)) 32 | last <- get_last(y) 33 | 34 | if (!is.na(last)){ 35 | rstudioapi::sendToConsole(last,execute = FALSE) 36 | }else{ 37 | cat(crayon::white$italic("No correction available")) 38 | } 39 | # rstudioapi::sendToConsole("ls()",execute = TRUE) 40 | cat("") 41 | blank<-"" 42 | class(blank)<-"blank" 43 | invisible(blank) 44 | 45 | } 46 | 47 | #' return corrected instruction 48 | #' 49 | #' @param n postion of the correction 50 | #' 51 | #' @export 52 | #' @examples 53 | #' get_last() 54 | get_last<-function(n=1){ 55 | message <- getOption("fcuk")[[2]] 56 | correction <- getOption("fcuk")[[1]] 57 | error <- getOption("fcuk")[[3]] 58 | le_call <- sub("Error in (.*) :.*" ,"\\1",message) 59 | # le_call %>% str_replace(pattern = error,replacement = correction)[n] 60 | sapply(correction,function(x){gsub(x=le_call,pattern = error,replacement = x)})[n] 61 | } 62 | 63 | #'@export 64 | print.blank <-function(x,...){ 65 | cat("") 66 | } -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | #' @noRd 2 | .onAttach <- function(libname, pkgname) { 3 | fcuk::init_error_tracker() 4 | } 5 | #' @noRd 6 | .onDetach <- function(libname) { 7 | fcuk::remove_error_tracker() 8 | } 9 | 10 | globalVariables(".") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/fcuk)](https://cran.r-project.org/package=fcuk) 2 | [![](http://cranlogs.r-pkg.org/badges/fcuk)](https://cran.r-project.org/package=fcuk) 3 | [![Travis build status](https://travis-ci.org/ThinkR-open/fcuk.svg?branch=master)](https://travis-ci.org/ThinkR-open/fcuk) 4 | [![Coverage status](https://codecov.io/gh/ThinkR-open/fcuk/branch/master/graph/badge.svg)](https://codecov.io/github/ThinkR-open/fcuk?branch=master) 5 | 6 | 7 | 8 | # fcuk 9 | 10 | A package designed to help people with clumsy fingers. 11 | 12 | 13 | ![](https://media.giphy.com/media/l0Iy8JGxnl5rE1Z96/giphy.gif) 14 | 15 | 16 | 17 | ## Installation of `fcuk` 18 | 19 | ### From CRAN 20 | ```R 21 | 22 | install.packages("fcuk") 23 | ``` 24 | 25 | 26 | ### From github 27 | ```R 28 | if (!require(devtools)){install.packages("devtools")} 29 | devtools::install_github("ThinkR-open/fcuk") 30 | ``` 31 | 32 | ## Launch and use 33 | 34 | See full documentation realised using {pkgdown} at 35 | 36 | After launching this package, every error will be analysed. Each time a typo occurs, a correction suggestion will be made under the default error message. 37 | 38 | ```{r} 39 | library(fcuk) 40 | 41 | # Examples 42 | sl() 43 | > Error in sl() : impossible de trouver la fonction "sl" 44 | Did you mean : ls or nls ? 45 | 46 | iri 47 | > Erreur : objet 'iri' introuvable 48 | Did you mean : IQR or iris ? 49 | 50 | view 51 | > Erreur : objet 'view' introuvable 52 | Did you mean : View or deriv ? 53 | 54 | mea 55 | > Erreur : objet 'mea' introuvable 56 | Did you mean : mean or frame ? 57 | 58 | ``` 59 | 60 | You can accept `fcuk` correction proposal by using this notation : `.+1` This allows you to rerun the last line by accepting the first correction proposal. 61 | In fact `.+n` will rerun the nth correction proposal. 62 | 63 | ```{r} 64 | library(fcuk) 65 | 66 | # Examples 67 | sl() 68 | > Error in sl() : impossible de trouver la fonction "sl" 69 | Did you mean : ls or nls ? 70 | > .+1 71 | > ls() 72 | 73 | ``` 74 | 75 | ## Stop `fcuk` 76 | 77 | You can stop `fcuk` at anytime by calling the `remove_error_tracker` function. Start the error tracker again with `init_error_tracker`. 78 | 79 | ## Recurrent use of fcuk 80 | 81 | You can launch `fcuk` with your R session. 82 | 83 | ```{r} 84 | .First <- function(){ 85 | cat("\n Bonjour ! - ", date(), "\n") 86 | library(fcuk) 87 | } 88 | ``` 89 | 90 | It will be more efficient to add this library to your Rprofile. You can use `fcuk::add_fcuk_to_rprofile()` to do so. Then, any time you launch your R project, `fcuk` will be launched at the same time. 91 | 92 | You can also add `fcuk` inside your `Rprofile.site` file. Then you'll have this functionality inside all your Rstudio projects. 93 | 94 | ## fcuk functions 95 | 96 | You'll typically never need to use the functions contained in `fcuk`. You just need to launch this library, and `fcuk` will do its job in the background. 97 | 98 | ## Feedbacks and questions 99 | 100 | Feel free to report any [issue](https://github.com/ThinkRstat/fcuk/issues) you may have with this package. 101 | 102 | ## Code of conduct 103 | 104 | Please note that the 'fcuk' project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. 105 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | template: 2 | package: thinkrtemplate 3 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | patch: 10 | default: 11 | target: auto 12 | threshold: 1% 13 | -------------------------------------------------------------------------------- /data-raw/devtools_tricks.R: -------------------------------------------------------------------------------- 1 | devtools::use_data_raw() 2 | devtools::use_package("stringdist") 3 | devtools::use_package("purrr") 4 | devtools::use_package("magrittr") 5 | devtools::use_package("tibble") 6 | devtools::use_vignette("poc") 7 | devtools::use_vignette("fcuk") 8 | devtools::build_vignettes() 9 | library(bookdown) 10 | bookdown::render_book("plop") 11 | devtools::use_test("regex") 12 | devtools::use_test("get_all_objets_from_r") 13 | devtools::use_test("error_correction_propostion") 14 | devtools::use_test("error_analysis") 15 | devtools::use_test("catch_error") 16 | 17 | -------------------------------------------------------------------------------- /data-raw/idee.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern SEXP R_CurrentExpr; 4 | 5 | // [[Rcpp::export]] 6 | SEXP current(){ return R_CurrentExpr ; } -------------------------------------------------------------------------------- /data-raw/langage.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | res <- c() 4 | for ( i in list.files("C:\\Program Files\\R\\R-3.4.0\\library\\translations")){ 5 | print(i) 6 | Sys.setenv(LANG = i) 7 | Sys.setenv(LANGUAGE =i) 8 | try(sl()) 9 | res <- c(res,geterrmessage()) 10 | try(iri) 11 | res <- c(res,geterrmessage()) 12 | } 13 | res<-c( 14 | "Error in sl() : \"sl\" fonksiyonu bulunamadi\n"="Error in sl() : \"sl\" fonksiyonu bulunamadi\n", 15 | "Error in sl() : could not find function \"sl\"\n"="Error in sl() : could not find function \"sl\"\n", 16 | "Error in sl() : fann ikkje funksjonen «sl»\n"="Error in sl() : fann ikkje funksjonen «sl»\n", 17 | "Error in sl() : impossible de trouver la fonction \"sl\"\n"="Error in sl() : impossible de trouver la fonction \"sl\"\n", 18 | "Error in sl() : konnte Funktion \"sl\" nicht finden\n"="Error in sl() : konnte Funktion \"sl\" nicht finden\n", 19 | "Error in sl() : não foi possível encontrar a função \"sl\"\n"="Error in sl() : não foi possível encontrar a função \"sl\"\n", 20 | "Error in sl() : nie udalo sie znalezc funkcji 'sl'\n"="Error in sl() : nie udalo sie znalezc funkcji 'sl'\n", 21 | "Error in sl() : no se pudo encontrar la función \"sl\"\n"="Error in sl() : no se pudo encontrar la función \"sl\"\n", 22 | "Error in sl() : non trovo la funzione \"sl\"\n"="Error in sl() : non trovo la funzione \"sl\"\n", 23 | "Error in try(iri) : 'iri' nesnesi bulunamadi\n"="Error in try(iri) : 'iri' nesnesi bulunamadi\n", 24 | "Error in try(iri) : fann ikkje objektet «iri»\n"="Error in try(iri) : fann ikkje objektet «iri»\n", 25 | "Error in try(iri) : nie znaleziono obiektu 'iri'\n"="Error in try(iri) : nie znaleziono obiektu 'iri'\n", 26 | "Error in try(iri) : object 'iri' not found\n"="Error in try(iri) : object 'iri' not found\n", 27 | "Error in try(iri) : object ‘iri’ not found\n"="Error in try(iri) : object ‘iri’ not found\n", 28 | "Error in try(iri) : objekt 'iri' blev ikke fundet\n"="Error in try(iri) : objekt 'iri' blev ikke fundet\n", 29 | "Error in try(iri) : Objekt 'iri' nicht gefunden\n"="Error in try(iri) : Objekt 'iri' nicht gefunden\n", 30 | "Error in try(iri) : objet 'iri' introuvable\n"="Error in try(iri) : objet 'iri' introuvable\n", 31 | "Error in try(iri) : objeto 'iri' não encontrado\n"="Error in try(iri) : objeto 'iri' não encontrado\n", 32 | "Error in try(iri) : objeto 'iri' no encontrado\n"="Error in try(iri) : objeto 'iri' no encontrado\n", 33 | "Error in try(iri) : oggetto \"iri\" non trovato\n"="Error in try(iri) : oggetto \"iri\" non trovato\n" 34 | ) 35 | gettext("could not find function",domain = "fr") 36 | 37 | 38 | 39 | c("Error in sl() : \"sl\" fonksiyonu bulunamadi\n", 40 | "Error in sl() : could not find function \"sl\"\n", "Error in sl() : fann ikkje funksjonen «sl»\n", 41 | "Error in sl() : impossible de trouver la fonction \"sl\"\n", 42 | "Error in sl() : konnte Funktion \"sl\" nicht finden\n", "Error in sl() : não foi possível encontrar a função \"sl\"\n", 43 | "Error in sl() : nie udalo sie znalezc funkcji 'sl'\n", "Error in sl() : no se pudo encontrar la función \"sl\"\n", 44 | "Error in sl() : non trovo la funzione \"sl\"\n", "Error in try(iri) : 'iri' nesnesi bulunamadi\n", 45 | "Error in try(iri) : fann ikkje objektet «iri»\n", "Error in try(iri) : nie znaleziono obiektu 'iri'\n", 46 | "Error in try(iri) : object 'iri' not found\n", "Error in try(iri) : object ‘iri’ not found\n", 47 | "Error in try(iri) : objekt 'iri' blev ikke fundet\n", "Error in try(iri) : Objekt 'iri' nicht gefunden\n", 48 | "Error in try(iri) : objet 'iri' introuvable\n", "Error in try(iri) : objeto 'iri' não encontrado\n", 49 | "Error in try(iri) : objeto 'iri' no encontrado\n", "Error in try(iri) : oggetto \"iri\" non trovato\n" 50 | ), .Names = c("Error in sl() : \"sl\" fonksiyonu bulunamadi\n", 51 | "Error in sl() : could not find function \"sl\"\n", "Error in sl() : fann ikkje funksjonen «sl»\n", 52 | "Error in sl() : impossible de trouver la fonction \"sl\"\n", 53 | "Error in sl() : konnte Funktion \"sl\" nicht finden\n", "Error in sl() : não foi possível encontrar a função \"sl\"\n", 54 | "Error in sl() : nie udalo sie znalezc funkcji 'sl'\n", "Error in sl() : no se pudo encontrar la función \"sl\"\n", 55 | "Error in sl() : non trovo la funzione \"sl\"\n", "Error in try(iri) : 'iri' nesnesi bulunamadi\n", 56 | "Error in try(iri) : fann ikkje objektet «iri»\n", "Error in try(iri) : nie znaleziono obiektu 'iri'\n", 57 | "Error in try(iri) : object 'iri' not found\n", "Error in try(iri) : object ‘iri’ not found\n", 58 | "Error in try(iri) : objekt 'iri' blev ikke fundet\n", "Error in try(iri) : Objekt 'iri' nicht gefunden\n", 59 | "Error in try(iri) : objet 'iri' introuvable\n", "Error in try(iri) : objeto 'iri' não encontrado\n", 60 | "Error in try(iri) : objeto 'iri' no encontrado\n", "Error in try(iri) : oggetto \"iri\" non trovato\n" 61 | ) 62 | 63 | names(regex_rules()) 64 | 65 | for ( sentence in names(regex_rules())){ 66 | regex_rules() %>% 67 | map_chr(~sub(.x,"\\1",sentence)) %>% 68 | unname() %>% 69 | .[. != sentence] %>% print 70 | } 71 | 72 | sub(".*konnte Funktion \"(.*)\" nicht finden\n", 73 | "\\1", 74 | "Error in sl() : konnte Funktion \"sl\" nicht finden\n") 75 | 76 | regex_rules() %>% 77 | map_chr(~sub(.x,"\\1",names(regex_rules())[5])) %>% 78 | # unname() %>% 79 | .[. != sentence] 80 | -------------------------------------------------------------------------------- /data-raw/test.R: -------------------------------------------------------------------------------- 1 | 1+1 2 | # ls(eert=1) 3 | 4 | f <- function(...){ 5 | 6 | for ( i in 1:10){ 7 | 8 | 9 | if (i ==6) { ls(rtertert=erg)} 10 | } 11 | 12 | } 13 | f() -------------------------------------------------------------------------------- /fcuk.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace,vignette 19 | -------------------------------------------------------------------------------- /img/fcuk-hex-thinkr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkR-open/fcuk/fc5b4c219548d22b22ceb1b0bdb9acda05d8d0ff/img/fcuk-hex-thinkr.png -------------------------------------------------------------------------------- /man/add_fcuk_to_rprofile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/add_to_rprofile.R 3 | \name{add_fcuk_to_rprofile} 4 | \alias{add_fcuk_to_rprofile} 5 | \title{Add library(fcuk) to the .Rprofile file} 6 | \usage{ 7 | add_fcuk_to_rprofile(global = TRUE) 8 | } 9 | \arguments{ 10 | \item{global}{Whether to add it to the global .Rprofile (\code{TRUE}) or just 11 | to the .Rprofile file of your current project (\code{FALSE}, the default).} 12 | } 13 | \description{ 14 | After calling this function, fcuk will be launched everytime you launch your 15 | current R project (or any project if you use option \code{global = TRUE}). 16 | } 17 | \examples{ 18 | fcuk::add_fcuk_to_rprofile() 19 | } 20 | -------------------------------------------------------------------------------- /man/catch_error.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{catch_error} 4 | \alias{catch_error} 5 | \title{Capture and parse an error message.} 6 | \usage{ 7 | catch_error(sentence = geterrmessage()) 8 | } 9 | \arguments{ 10 | \item{sentence}{an error message to parse} 11 | } 12 | \description{ 13 | Capture and parse an error message. 14 | } 15 | \examples{ 16 | catch_error() 17 | catch_error("Error: object 'iri' not found\\n") 18 | catch_error("Error: object 'view' not found\\n") 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/error_analysis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{error_analysis} 4 | \alias{error_analysis} 5 | \title{Error Analysis} 6 | \usage{ 7 | error_analysis(asked_objet = catch_error(), n = 2) 8 | } 9 | \arguments{ 10 | \item{asked_objet}{the name to analyse} 11 | 12 | \item{n}{number of names to suggest} 13 | } 14 | \description{ 15 | Error Analysis 16 | } 17 | \examples{ 18 | fcuk::error_analysis() #last error is analysed 19 | fcuk::error_analysis("view") 20 | fcuk::error_analysis("iri") 21 | } 22 | -------------------------------------------------------------------------------- /man/error_correction_propostion.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{error_correction_propostion} 4 | \alias{error_correction_propostion} 5 | \title{Find closest object names} 6 | \usage{ 7 | error_correction_propostion(asked_objet, method = "jaccard", n = 2) 8 | } 9 | \arguments{ 10 | \item{asked_objet}{the R name producing an error} 11 | 12 | \item{method}{Method for distance calculation. The default is "jaccard", see \link[stringdist]{stringdist-metrics}.} 13 | 14 | \item{n}{number of corrections to suggest.} 15 | } 16 | \value{ 17 | a character vector with the closest neighbors 18 | } 19 | \description{ 20 | Analyse a typo and suggests the two closest names. 21 | } 22 | \examples{ 23 | error_correction_propostion("iri") 24 | } 25 | -------------------------------------------------------------------------------- /man/fcuk-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/doc_package.R 3 | \docType{package} 4 | \name{fcuk-package} 5 | \alias{fcuk} 6 | \alias{fcuk-package} 7 | \title{fcuk: The Ultimate Helper for Clumsy Fingers} 8 | \description{ 9 | Automatically suggests a correction when a typo occurs. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://github.com/ThinkRstat/fcuk} 15 | \item Report bugs at \url{https://github.com/ThinkRstat/fcuk/issues} 16 | } 17 | 18 | } 19 | \author{ 20 | \strong{Maintainer}: Vincent Guyader \email{vincent@thinkr.fr} (0000-0003-0671-9270) 21 | 22 | Other contributors: 23 | \itemize{ 24 | \item ThinkR [copyright holder] 25 | } 26 | 27 | } 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /man/get_all_objets_from_r.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{get_all_objets_from_r} 4 | \alias{get_all_objets_from_r} 5 | \title{Extract the name of all objects loaded in the R environments} 6 | \usage{ 7 | get_all_objets_from_r() 8 | } 9 | \value{ 10 | a list with the names of all objects contained in the environments 11 | } 12 | \description{ 13 | Fetch the name of all objects loaded in the environments (functions, values, data...) 14 | } 15 | \examples{ 16 | get_all_objets_from_r() 17 | } 18 | -------------------------------------------------------------------------------- /man/get_last.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerun.R 3 | \name{get_last} 4 | \alias{get_last} 5 | \title{return corrected instruction} 6 | \usage{ 7 | get_last(n = 1) 8 | } 9 | \arguments{ 10 | \item{n}{postion of the correction} 11 | } 12 | \description{ 13 | return corrected instruction 14 | } 15 | \examples{ 16 | get_last() 17 | } 18 | -------------------------------------------------------------------------------- /man/init_error_tracker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{init_error_tracker} 4 | \alias{init_error_tracker} 5 | \title{Init error tracker} 6 | \usage{ 7 | init_error_tracker() 8 | } 9 | \description{ 10 | After lauching this function, every error message will be analysed. 11 | This function is called when loading the package. 12 | } 13 | \examples{ 14 | getOption("error") 15 | fcuk::init_error_tracker() 16 | getOption("error") 17 | } 18 | -------------------------------------------------------------------------------- /man/plus-.fcuk.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerun.R 3 | \name{+.fcuk} 4 | \alias{+.fcuk} 5 | \title{Rerun with correcyion} 6 | \usage{ 7 | \method{+}{fcuk}(x, y) 8 | } 9 | \arguments{ 10 | \item{x}{blank object of class fcuk} 11 | 12 | \item{y}{an integer corresponding to the position of the proposal to be reused} 13 | } 14 | \description{ 15 | Rerun with correcyion 16 | } 17 | \examples{ 18 | \dontrun{ 19 | view(iris)# error 20 | .+1 # return View(iris) 21 | 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/remove_error_tracker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/function.R 3 | \name{remove_error_tracker} 4 | \alias{remove_error_tracker} 5 | \title{Remove error tracker} 6 | \usage{ 7 | remove_error_tracker() 8 | } 9 | \description{ 10 | After lauching this function, the errors will no longer be analysed. 11 | } 12 | \examples{ 13 | getOption("error") 14 | fcuk::remove_error_tracker() 15 | getOption("error") 16 | } 17 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(fcuk) 3 | 4 | test_check("fcuk") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-catch_error.R: -------------------------------------------------------------------------------- 1 | context("catch_error") 2 | 3 | test_that("catch_error works", { 4 | library(purrr) 5 | out <- fcuk:::regex_rules()$error %>% 6 | map_chr(~catch_error(.x)) %>% 7 | unique() 8 | 9 | expect_equal(out, c("sl","iri","dplir")) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/test-erreur_correction_propostion.R: -------------------------------------------------------------------------------- 1 | context("error_correction_propostion") 2 | 3 | test_that("error_correction_propostion works", { 4 | expect_equal(error_correction_propostion("view")[1],"View") 5 | expect_equal(error_correction_propostion("sl")[1],"ls") 6 | }) 7 | -------------------------------------------------------------------------------- /tests/testthat/test-error_analysis.R: -------------------------------------------------------------------------------- 1 | context("error_analysis") 2 | 3 | test_that("fcuk::error_analysis works", { 4 | expect_match(error_analysis("iri"),"iris") 5 | # expect_match(error_analysis("dplir"),"dplyr") 6 | }) 7 | -------------------------------------------------------------------------------- /tests/testthat/test-get_all_objets_from_r.R: -------------------------------------------------------------------------------- 1 | context("get_all_objets_from_r") 2 | 3 | test_that("multiplication works", { 4 | expect_is(get_all_objets_from_r(), "character") 5 | }) 6 | -------------------------------------------------------------------------------- /tests/testthat/test-regex.R: -------------------------------------------------------------------------------- 1 | context("regex") 2 | 3 | test_that("regex ok ", { 4 | library(purrr) 5 | hop <- c() 6 | for ( sentence in fcuk:::regex_rules()$error){ 7 | hop <- c(hop, fcuk:::regex_rules()$regex %>% 8 | map_chr(~sub(.x,"\\1",sentence)) %>% 9 | unname() %>% 10 | .[. != sentence] ) 11 | } 12 | expect_true(setequal(sort(unique(hop)),c("dplir","iri","sl"))) 13 | }) 14 | -------------------------------------------------------------------------------- /vignettes/fcuk.R: -------------------------------------------------------------------------------- 1 | ## ----eval=FALSE---------------------------------------------------------- 2 | # library(fcuk) 3 | # 4 | # # Examples 5 | # sl() 6 | # > Error in sl() : impossible de trouver la fonction "sl" 7 | # Did you mean : ls or nls ? 8 | # 9 | # iri 10 | # > Erreur : objet 'iri' introuvable 11 | # Did you mean : IQR or iris ? 12 | # 13 | # view 14 | # > Erreur : objet 'view' introuvable 15 | # Did you mean : View or deriv ? 16 | # 17 | # mea 18 | # > Erreur : objet 'mea' introuvable 19 | # Did you mean : mean or frame ? 20 | # 21 | 22 | ## ------------------------------------------------------------------------ 23 | .First <- function(){ 24 | cat("\n Bonjour ! - ", date(), "\n") 25 | library(fcuk) 26 | } 27 | 28 | -------------------------------------------------------------------------------- /vignettes/fcuk.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to fcuk" 3 | author: "Vincent Guyader" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Introduction to fcuk} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | # fcuk 13 | 14 | A package designed to help people with clumsy fingers. 15 | 16 | ## Installation of `fcuk` 17 | 18 | ```R 19 | if (!require(devtools)){install.packages("devtools")} 20 | devtools::install_github("ThinkRstat/fcuk") 21 | ``` 22 | 23 | ## Launch and use 24 | 25 | After launching this package, every error will be analysed. Each time a typo occurs, a correction suggestion will be made under the default error message. 26 | 27 | ```{r eval=FALSE} 28 | library(fcuk) 29 | 30 | # Examples 31 | sl() 32 | > Error in sl() : impossible de trouver la fonction "sl" 33 | Did you mean : ls or nls ? 34 | 35 | iri 36 | > Erreur : objet 'iri' introuvable 37 | Did you mean : IQR or iris ? 38 | 39 | view 40 | > Erreur : objet 'view' introuvable 41 | Did you mean : View or deriv ? 42 | 43 | mea 44 | > Erreur : objet 'mea' introuvable 45 | Did you mean : mean or frame ? 46 | 47 | ``` 48 | 49 | ## Stop `fcuk` 50 | 51 | You can stop `fcuk` at anytime by calling the `remove_error_tracker` function. Start the error tracker again with `init_error_tracker`. 52 | 53 | ## Recurrent use of fcuk 54 | 55 | You can launch `fcuk` with your R session. 56 | 57 | ```{r} 58 | .First <- function(){ 59 | cat("\n Bonjour ! - ", date(), "\n") 60 | library(fcuk) 61 | } 62 | ``` 63 | 64 | It will be more efficient to add this library to your Rprofile. You can use `fcuk::add_fcuk_to_rprofile()` to do so. Then, any time you launch your R project, `fcuk` will be launched at the same time. 65 | 66 | You can also add `fcuk` inside your `Rprofile.site` file. Then you'll have this functionnality inside all your Rstudio projects. 67 | 68 | ## fcuk functions 69 | 70 | You'll typically never need to use the functions contained in `fcuk`. You just need to launch this library, and `fcuk` will do his job in the background. 71 | 72 | ## Feedbacks and questions 73 | 74 | Feel free to report any [issue](https://github.com/ThinkRstat/fcuk/issues) you may have with this package. --------------------------------------------------------------------------------