opto abhi
opto abhi

Reputation: 317

MATLAB auto completing start and end statements of code body?

Is it possible in MATLAB to automatically insert start and end of a code body ? For example: classdef and end; function and end; methods and end.

 classdef Circle
        properties
            radius
        end
        methods
            function dia = FindDia(obj)
                dia = [obj.radius]*2;
            end
            function %no automatic insertion of 'end'
        end    
    end

Upvotes: 2

Views: 95

Answers (1)

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38042

Since I work regularly in so many different editors, I don't rely on any one editor's features. It's a pain to learn them all and keep the configuration for all these editors in sync, on all my machines. Often, it's useful to have the same feature set I'm used to, in editors not even meant for code (like MS Word, or here on Stack Overflow).

Therefore, I use AutoHotkey for this kind of thing (and Autokey on Linux).

For functions and classes, I use a paste function to paste a specific template file, depending on whether I'm at work or at home, and which project I'm working on. A small GUI then asks me for the function or class name, which it then populates the template with. I can share that too if you want.

Below are a few AutoHotkey functions and hotstrings I use for including the end keyword. Note that this might all seem overly complex just to put an end there, and in this case, it probably is. But the clipCopy, clipPaste and getIndent functions have proven their usefulness in the rest of my programming snippets, and I hope they might be for you too.

I've thrown in the error functions as well, just because.

; Copy selected text
; More robust than C-c/C-x/C-v; see  
; https://autohotkey.com/board/topic/111817-robust-copy-and-paste-routine-function/
clipCopy(dontRestoreClipboard := 0)
{
    prevClipboard := Clipboard
    Clipboard := ""

    copyKey := "vk43sc02E" ; Copy

    SendInput, {Shift Down}{Shift Up}{Ctrl Down}{%copyKey% Down}
    ClipWait, 0.25, 1
    SendInput, {%copyKey% Up}{Ctrl Up}

    str := Clipboard

    if (dontRestoreClipboard == 0)
        Clipboard := prevClipboard 

    return str
}

clipPaste(ByRef txt, dontBackupClipboard := 0)
{
    if (txt != "")
    {
        prevClipboard := ""

        pasteKey := "vk56sc02F" ; Paste


        if (dontBackupClipboard == 0) {
            prevClipboard := Clipboard
            Clipboard := ""
        }

        Clipboard := txt
        ClipWait, 1.00, 1

        ; Start pressing paste key
        SendInput, {Shift Down}{Shift Up}{Ctrl Down}{%pasteKey% Down}

        ; Wait until clipboard is ready
        startTime := A_TickCount
        while (DllCall("GetOpenClipboardWindow") && (A_TickCount - startTime < 1000)) {
            Sleep, 50
        }

        ; Release paste key
        SendInput, {%pasteKey% Up}{Ctrl Up}

        ; TODO: a manual delay still seems necessary...this vlaue needs to be this large, to also have
        ; correct behavior in superslow apps like MS Office, Outlook, etc. Sadly, the SetTimer approach
        ; does not seem to work (doesn't correctly restore the clipboard); to be investigated.
        Sleep 333

        ; Put previous clipboard content back onto the clipboard
        Clipboard := prevClipboard 
    }
}

; Get current indentation level in an editor-independent way
getIndent(dontRestoreClipboard := 0)
{
    ; Select text from cursor to start of line
    SendInput, +{Home}

    indent := clipCopy(dontRestoreClipboard)
    numsp  := 0
    if (indent != "")
        indent := RegExReplace(indent, ".", " ", numsp)

    ; Undo selection (this is tricky; different editors often have
    ; different behavior for Home/End keys while text is selected
    SendInput, {Right}{Left}{Home}

    ; NOTE: don't use {End}, because we might be in the middle of a sentence
    ; Use the "right" key, repeatedly
    Loop, %numsp% {
        SendInput, {Right}
    }

    return indent
}

mBasic(str)
{
    current_indent := getIndent()
    SendInput, %str% (){Enter}+{Home}%current_indent%{Space 4}{Enter}+{Home}%current_indent%end{Up 2}{End}{Left}
}

mErrfcn(str)
{
    current_indent := getIndent()
    spaces := RegExReplace(str, ".", " ")
    clipPaste(str . "([mfilename ':default_errorID'],...`r`n" . current_indent . spaces . " 'Default error string.');")

    return current_indent
}



; MATLAB Hotstrings for basic control structures
:o:mfor::
    mBasic("for")
return

:o:mpar::
    mBasic("parfor")
return

:o:mwhile::
    mBasic("while")
return

:o:spmd::
    mBasic("spmd")
return

:o:mif::
    mBasic("if")
return

; ...etc.


; error, warning, assert
:o:merr::
:o:merror::
    mErrfcn("error")
    SendInput, {Up}{End}{Left 21}
return

:o:mwarn::
:o:mwarning::
    mErrfcn("warning")
    SendInput, {Up}{End}{Left 21}
return

_mlAssert()
{
    current_indent := mErrfcn("assert")
    SendInput, {Up}{End}{Left 34}true,...{Enter}+{Home}%current_indent%{Space 7}{Up}{End}{Left 8}
}
:o:massert::
    _mlAssert()
return

Upvotes: 2

Related Questions