VScode도magrittr 파이프를 더 잘 입력할 수 있도록 VScode 확장 기능 제작에 도전해 봅시다

R 언어의 파이핑


이 글은 VScode에서 R 언어 프로그래밍을 할 때 입력 파이프의 키보드 단축키를 실현하는 방법을 소개했다.
R 언어에 bash terminal 파이프와 비슷한 것이 존재합니다.가방magrittr을 통해 산수%>%를 실현했고 최근 발표된 R4.1.0 이후 타사 포장에 의존하지 않는 네이티브 피프|>를 도입해 화제가 되기도 했다.최신 Native pipe내 블로그에 대해 설명 좀 해주시고 가능하면 참고하세요.
https://excel2rlang.com/base-pipe-r420/
파이프 연산자는 다음과 같습니다.
library(tidyverse)

starwars %>%
    filter(height > 100) %>%
    group_by(species) %>%
    summarise(mass_mean = mean(mass))
R은 대체적으로 느슨한 코드 규약이 있고 tidyverse style guide에서 파이프에 대해 다음과 같은 규칙을 규정했다.
  • 파이프 연산자 앞에 공간 배치
  • 파이프 연산자 후 바로 줄 바꾸기
  • 첫 번째 파이프 뒤에 밀어넣기
  • VScode를 사용하여 파이프의 키보드 단축키 설정하기


    R스튜디오{Ctrl} + {Shift} + {m}에서 파이프 입력의 단축키로 설정됩니다.이 키보드 단축키는 VS코드가 탄생하기 전부터 존재해 몸에 침투했다.따라서 VScode도 그런 단축키를 설정하고 싶지만gug라면 금방 찾을 수 있어요.라고 답했다.keybindings.json에 다음과 같은 내용을 추가하면 R스튜디오와 같은 키보드 단축키를 간단하게 설정할 수 있다.
    [
        {
            "key": "Ctrl+Shift+m",
            "command": "type",
            "args": {
                "text": " %>% "
            },
            "when": "editorTextFocus && editorLangId == r"
        },
        {
            "key": "Alt+-",
            "command": "type",
            "args": {
                "text": " <- "
            },
            "when": "editorTextFocus && editorLangId == r"
        },
    
    ]
    
    editorLangIdrmdqmd 등을 넣는 것이 좋다.

    VScode 파이핑 단축키 개선


    아까 키보드 단축키를 미리 설정하면 대체로 R 인코딩을 쉽게 할 수 있지만, 아쉽게도 줄 끝의 공백(공간)이 있든 없든 공백이 있는 파이프%>%를 입력한다.R스튜디오의 파이프 키보드 단축키는 줄 끝에 공백이 있는지 여부를 판단할 수 있어 두 개의 공백이 없을 정도로 맛이 난다.

    Rstudio는 공백을 잘 알 수 있어요.

    VScode 키보드 단축키만 공백이 반복되는 경우가 있습니다.
    가능하다면 VS코드에서도 같은 규격의 키보드 단축키를 만들 수 있을 거라고 생각했는데 찾아보니 확장 기능으로 실현하는 것 외에 다른 방법이 없는 것 같아요.😰이 때문에 자바스크립트를 전혀 접하지 못한 필자는 VScode API를 조사하면서 고된 전투를 벌여 드디어 움직이기 시작했다.

    확장 기능 개발 환경 준비


    포장화된 경험을 한 후에 저는 공식 설명 매우 이해하기 쉽다고 생각했습니다. VScode 자신의 건의 내용을 통해 API 규격 정보는 대부분이 알 수 있습니다.확장 기능 개발에 어려움을 겪으면 볼 수 있다API reference.
    먼저 Your First Extension와 같이 폴더를 준비합니다.
    !
    WSL2에서 작성한 Ubuntu20입니다.04 다음을 수행합니다.
    # いつかにインストールしたnvmを使ってnpmバージョンを変える
    nvm use v18.1.0
    
    yarn install -g yo generator-code
    yo code
    
    # ? What type of extension do you want to create? New Extension (TypeScript)
    # ? What's the name of your extension? convertRCode
    ### Press <Enter> to choose default for all options below ###
    
    # ? What's the identifier of your extension? convertRCode
    # ? What's the description of your extension? VSCode R utils
    # ? Initialize a git repository? Yes
    # ? Bundle the source code with webpack? No
    # ? Which package manager to use? yarn
    
    # ? Do you want to open the new folder with Visual Studio Code? Open with `code`
    
    실행yo code 후 이상한 지장보살 같은 아스키 예술이 나타나 질문에 대답하면서 전진하면 필요한 파일을 포함하는 목록이 자동으로 생성된다.

    extensions.ts 편집

    extensions.ts는 기능을 확장하는 호스트인 것 같습니다.VScode의 리소스 매니저 화면에서 extensions.ts를 선택한 상태에서 F5 키를 누르면 extensions.ts를 확장 기능으로 마운트한 상태의 창이 팝업됩니다.
    그래서 샘플 코드로 실시된 명령Hello world은 명령 트레이에서 실행 가능한 상태로 바뀌었습니다!typescript를 살짝 쓰고 F5로 디버깅을 하면 이런 절차는 개발하기 매우 쉽다😲
    그리고 공식적인 API 참조와javascript의 문자열 처리 방법 등을 조사해 다음 기능을 적었다.
    export function activate(context: vscode.ExtensionContext) {
    	
        let _ = vscode.commands.registerCommand('transformrcode.addmagrittrpipe', function() {
            
            const editor = vscode.window.activeTextEditor;
            
            if (editor) {
                // 現在の行rangeを取得
                let currentline = editor.document.lineAt(editor.selection.active.line).range;
                // 現在の行のstringsを取得
                let currentstring = editor.document.lineAt(editor.selection.active.line).text;
                
                if (currentstring.endsWith(" ")) {
                    let result = currentstring+"%>%";
                    editor.edit(edit => edit.replace(currentline, result))
                    .then(success => {
                        var position = editor.selection.end;
                        editor.selection = new vscode.Selection(position, position);
                    });
                } else {
                    let result = currentstring+" %>%";
                    editor.edit(edit => edit.replace(currentline, result))
                    .then(success => {
                        var position = editor.selection.end;
                        editor.selection = new vscode.Selection(position, position);
                    });
                }
            }
        });
    }
    
    참고서에서 단번에 잘 보이지 않는 것은 커서 위치의 줄의 문자열을 어떻게 얻었는지, 표의 문자열을 어떻게 변경했는지 하는 것이다.또 한 번의 기능으로 동작을 확인한 뒤 입력%>%이 선택된 상태로 바뀌었기 때문에 어떻게 문자열을 바꾼 뒤 선택을 해제할 수 있는지도 어려웠다.
    중요한 공백 인식은 조건이 엇갈리는 간단한 구조로 쓴 것이 아니냐는 것이다.나는 typescript의 기초를 배우지 못했다. 변수의 처리에 대해 전혀 이해하지 못하기 때문에 매우 지루하고 장황한 코드를 썼다고 생각했지만, 지금은 그만두었다.👋
    또한 package.json에는 다음과 같은 명령이 정의되어 있습니다.해보니까 명령 트레이contributes.commands.title에 기술된 문자열에fuzy search가 있는 것 같아.
    	"activatVonEvents": [
            "onCommand:transformrcode.addmagrittrpipe"
    	],
    	"contributes": {
    		"commands": [
                {
                    "command": "transformrcode.addmagrittrpipe",
                    "title": "add magrittr pipe"
                }
    		]
    	},
    

    패키지 설치


    마지막으로 참고공식적인 "publishing extension"에 작성된 스크립트를 패키지로 설치합니다.
    yarn install -g vsce
    yarn vsce package
    
    이때 저자의 이름과 허가증 등을 잘 기술하지 못했기 때문에 "응, 내 소원은..."잠깐만, 그런데, yyy와 전진해.그리고 transformrcode-0.0.1.vsix라는 패키지 파일을 출력하고 오른쪽 키로 =>확장 기능의 VSIX 설치를 완료하세요!

    키보드 단축키 정의


    이 작업에서 명령 팔레트%>%를 입력할 수 있지만 키보드 단축키를 정의하는 것이 마지막 방법입니다.
    VScodekeybindings.json에 아래 내용을 입력하면 가려운 곳을 건드리는 파이프 단축키를 완성할 수 있습니다!🦚
        {
            "key": "ctrl+shift+m",
            "command": "transformrcode.addnativepipe",
            "when": "editorTextFocus"
        },
    

    공백이 있어도 중복되지 않는다!

    사은품: Native pipe|>도 미리 설치


    방금extensions.ts에 아래 내용을 미리 적어 놓으면 네이티브 피프|>도 입력할 수 있다.
    export function activate(context: vscode.ExtensionContext) {
    	
        let __ = vscode.commands.registerCommand('transformrcode.addnativepipe', function() {
            
            const editor = vscode.window.activeTextEditor;
            
            if (editor) {
                // 現在の行rangeを取得
                let currentline = editor.document.lineAt(editor.selection.active.line).range;
                // 現在の行のstringsを取得
                let currentstring = editor.document.lineAt(editor.selection.active.line).text;
                
                if (currentstring.endsWith(" ")) {
                    let result = currentstring+"|>";
                    editor.edit(edit => edit.replace(currentline, result))
                    .then(success => {
                        var position = editor.selection.end;
                        editor.selection = new vscode.Selection(position, position);
                    });
                } else {
                    let result = currentstring+" |>";
                    editor.edit(edit => edit.replace(currentline, result))
                    .then(success => {
                        var position = editor.selection.end;
                        editor.selection = new vscode.Selection(position, position);
                    });
                }
            }
        });
    }
    
    이후 수행된 명령 등을 변경하면 파이프의 종류를 임기응변으로 변경할 수 있다💥

    끝말


    따라서 VSCODE 확장 기능을 만들어 좋은 느낌을 주는 파이프 입력 방법입니다.
    1∼2년 모두 R에서 파이톤으로 데이터 해석을 옮기는 축이었으나 사내에서 R에 대한 강연이 시작된 틈을 타 다시 R에 진입했다.이번에 살짝 접한 네이티브 피프keybindings.json가 재설치됐고, 토치와 커스도 R에서 사용할 수 있어 R이 많이 발전한 것 같아요.🤔
    그럼 안녕히 계세요!이 기사가 도움이 됐으면 좋겠어요.🌟
    (알림) 초보자를 위한 R 블로그가 시작되었습니다.
    https://excel2rlang.com

    좋은 웹페이지 즐겨찾기