• Extendedly basic vim setup

    Ahoy Internet, here’s a neat and fairly simple vim configuration for programming. Feel free to copy over settings/plugins you find useful, or just download a repository from GitHub with settings and plugins.

    The .vimrc file

    """""""""""""""""""""""""""""""""""""""
    " => Editing
    """""""""""""""""""""""""""""""""""""""
    
    syntax on
    
    " Indentation settings
    set tabstop=4
    set shiftwidth=4
    set smartindent
    set autoindent
    set expandtab
    
    " Disable backups and .swp files
    set nobackup
    set nowritebackup
    set noswapfile
    
    " Ignore case when searching
    set ignorecase
    set smartcase
    
    """""""""""""""""""""""""""""""""""""""
    " => Looks
    """""""""""""""""""""""""""""""""""""""
    
    colorscheme darkburn
    set background=dark
    
    " Set terminal window title
    set title
    
    " Shorten press ENTER to continue messages
    set shortmess=atI
    
    " Show last command
    set showcmd
    
    " Highlight cursor line
    set cursorline
    
    " Ruler (line, column and % at the right bottom)
    set ruler
    
    " Enable wild menu (tab command autocompletion)
    set wildmenu
    set wildmode=list:longest,full
    
    " Warn if exceed 80 columns limit
    if (&ft == 'python')
        highlight OverLength ctermbg=red ctermfg=white guibg=#592929
        match OverLength /%81v.+/
    endif
    
    """""""""""""""""""""""""""""""""""""""
    " => Misc
    """""""""""""""""""""""""""""""""""""""
    
    " Use Unix as the standart file type
    set ffs=unix,dos,mac
    
    " Enable filetype plugins
    filetype plugin on
    filetype indent on
    
    " Ignore compiled files
    set wildignore=*.o,*~,*.pyc,*.pyo
    
    """""""""""""""""""""""""""""""""""""""
    " => Plugins
    """""""""""""""""""""""""""""""""""""""
    
    " EasyMotion: one leader key instead of two
    let g:EasyMotion_leader_key = '<Leader>'
    
    " NERDTree: auto open and close
    autocmd VimEnter * NERDTree
    autocmd WinEnter * call s:CloseIfOnlyNerdTreeLeft()
    
    " NERDTree: focus on text window (left)
    autocmd VimEnter * wincmd l
    autocmd BufNew * wincmd l
    
    " NERDTree: auto close if last window
    function! s:CloseIfOnlyNerdTreeLeft()
        if exists("t:NERDTreeBufName")
            if bufwinnr(t:NERDTreeBufName) != -1
                if winnr("$") == 1
                    q
                endif
            endif
        endif
    endfunction
    
    " Exuberant Ctags: autogenerate on py file write
    au BufWritePost *.py silent! !ctags -R &
    
    " Pydoc: open in new tab instead of split
    let g:pydoc_open_cmd = 'tabnew'
    
    " Pydoc: disable search term highlight
    let g:pydoc_highlight=0
    

    Plugins

    If you are not planning to use some of the plugins, make sure to remove plugin-specific rules from .vimrc => Plugins.

    • Exuberant Ctags: allows you to generate index of variables, functions and classes to freely move between them. A bit more info on how to use these in article Using vim for writing code.
    • Colo(u)r Sampler Pack is not really a plugin, but a collection of color shemes. 100 of them, to be precise. Feel free to choose whatever you like.
    • ScrollColors allows you to try out every theme in visual mode. Just type in :SCROLL.
    • EasyMotion allows you to move between words, lines and sentences with a lightning speed. Just hit <Leader> + w to jump to one of the words forward or <Leader> + b backward (leader key is a backslash by default). It can do more neat things, documentation is pretty self-explanatory.
    • NERDTree is a directory tree, like in all modern IDEs (but of course better).
    • tComment allows you to easily comment out blocks of code. Hit gcc to comment a line or gc while selecting a block in Visual mode.

    Source

    You may want to head over to GitHub and grab a version from here: https://github.com/ruslanosipov/dotfiles.

  • Using vim for writing code

    Vim is a great text editor which can be much more powerful then any GUI editor or IDE. It has its learning curve, but once you are used to it you’ll never want to switch to anything else. Here’s a quick tutorial on how to use and customize vim for working with code.

    Basics

    Feel free to skip this first part if you are familiar with vim already.

    First, let’s get the hang of moving around. You can use arrow keys or h, j, k and l to move around. Holding Ctrl while moving will allow you to move between words (separated by spaces, tabulation, or line breaks), holding Shift allows you to do so with all punctuation characters including spaces and line breaks.

    Typing :147 will get you to the line 147, /foo will get you to the first occurrence of foo, / will repeat the last search.

    Hit i to enter insert mode and type in text. Hit Esc to go back. Key a does the same thing, but sets the cursor after the selected character. Hit Insert to switch between insert and replace modes.

    Typing in :w will write changes to a file, :q exits the editor, `:e

    ` opens another file. Sometimes you need to do some copy-pasting: copy (yank) line with `Y` and paste it with `p`. You should know that vim allows you to prefix the majority of commands with a number: typing in `13Y` will yank 13 lines, `40j` will take you 40 lines down, etc. Command `x` will delete a character, `dd` will delete a whole line. Of course, you can prefix it with a number if you need to delete more then one line. `:%s/foo/bar` will find and replace the first occurrence of foo with bar, `:%s/foo/bar/g` will do so within the whole file. Splitting windows is very helpful tool: `:split ` will split the window horizontally, `:vsplit ` will do so vertically. Hit `Ctrl + w`, and then arrow key will select an active view, `Ctrl + w, r` will swap the views. Simply type `:q` to close the window. ## Customizing Here's example of a `~/.vimrc` file, and the basic options necessary for editing code with vim. syntax on set tabstop=4 set shiftwidth=4 set smartindent set autoindent set expandtab Option `syntax on` enables syntax highlight, `tabstop` sets tab width, `shiftwidth` sets tab width for auto indentation, `smartindent`, `autoindent` enables indentation (smart indentation implies adding an extra indentation level after defining function, starting a loop, etc.), optional is `expandtab`, which tells vim to treat all tabs as spaces. If you are fan of limiting line width with n columns - add option `colorcolumn=80`, or (if your vim version is below 7.3) add the following lines: highlight OverLength ctermbg=red ctermfg=white guibg=#592929 match OverLength /%80v.+/ That should highlight all text exceeding the 80 columns limit. Feel free to experiment with the options and start building up your own `.vimrc`. ## Using ctags with vim [Exuberant Ctags](http://ctags.sourceforge.net/) allows you to create "tags" for all your classes, functions, and variables to allow easily jumping between them. After installing ctags (package is also available in major repositories named `ctags`) generate tags: $ cd project/ $ ctags -R * Open the main project file and move your cursor over to some function call. Hit `Ctrl + ]` to move to function definition, `:tn` will move you to the next definition for the function. Hitting `Ctrl + t` will return you back. Auto completion allows you not to bother with finishing words, variable or function names, and pretty much anything. That being said, `Ctrl + n` will finish the word for you or allow you to select the desired word from the list. This is just a basic example of what you can do with vim, for further info you can read [vim documentation](http://www.vim.org/docs.php). I may be posting some more tips and tricks on using vim in future.
  • C - Reallocating memory for the array

    I justĀ startedĀ delving into C and I had some issues with increasing the memory allocation size for my array. The best way to understand something - write a detailed explanation of the process. So here we go:

    #include <stdio.h>
    #include <stdlib.h>
    
    // notice that array is a pointer to a pointer
    int append_array_element(int **array, int *array_length, int element) {
        *array_length += 1;
        *array = realloc(*array, *array_length * sizeof(int));
        (*array)[*array_length - 1] = element; // [] has higher priority
                                               // then * in C's order of
        return 0;                              // operations
    }
    

    We have a pointer to the pointer to the array, pointer to the array’s length, and a value to append to the array. Array is passed as a pointer to pointer so we will be able to ā€˜repoint’ the original pointer to a new memory segment.

    Let’s call the function a few times and see what it gives us.

    int main() {
        int *array = NULL;
        int array_length = 0;
    
        append_array_element(&array, &array_length, 142);
        printf ("Our array with %d elementsn", array_length);
        printf("%dn", array[0]);
    
        append_array_element(&array, &array_length, 19);
        printf ("Our array with %d elementsn", array_length);
        printf("%dn", array[0]);
        printf("%dn", array[1]);
    
        return 0;
    }
    

    And the output is:

    Our array with 1 elements
    142
    Our array with 2 elements
    142
    19
    

    You can never be sure when you work with memory, so let’s add some error handling in case the operation fails.

    int append_array_element(int **array, int *array_length, int element) {
        *array_length += 1;
        // realloc() returns pointer or False if it fails
        void *_tmp_array = realloc(*array, *array_length * sizeof(int));
        if (!_tmp_array) {
            printf("Error while trying to realloc memory!n");
            return -1;
        }
        *array = _tmp_array;
        (*array)[*array_length - 1] = element;
    
        return 0;
    }
    

    Now we will be able to handle the crash on our own. But reallocation is not a very fast thing, so let’s double the amount of reallocated memory every time we run out of allocated memory. We’ll need one more variable to track the current allocated memory size.

    int append_array_element(int **array, int *array_length,
                             int *array_alloc_length, int element) {
        *array_length += 1;
        if (*array_length > *array_alloc_length) {
            if (*array_alloc_length == 0) {
                *array_alloc_length = 1;
            } else {
                *array_alloc_length *= 2;
            }
    
            void *_tmp_array = realloc(*array, *array_alloc_length * sizeof(int));
            if (!_tmp_array) {
                printf("Error while trying to reallocate memory for an array!n");
                return -1;
            }
            *array = _tmp_array;
        }
        (*array)[*array_length - 1] = element;
    
        return 0;
    }
    

    Let’s call it few times:

    int main() {
        int *array = NULL;
        int array_length = 0;
        int array_alloc_length = 0;
    
        int i;
        for (i = 0; i < 10; i++) {
            append_array_element(&array, &array_length, &array_alloc_length, i);
        }
    
        printf("Our array with %d elementsn", array_length);
        for (i = 0; i < 10; i++) {
            printf("%dn", array[i]);
        }
        printf("Array length: %d, allocated elements: %dn",
               array_length, array_alloc_length);
    
        return 0;
    }
    
    Our array with 10 elements
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Array length: 10, allocated elements: 16
    

    And for the fun of it, let’s do the same with 100 elements:

    Our array with 100 elements
    0
    1
    2
    ...
    97
    98
    99
    Array length: 100, allocated elements: 128
    

    Let’s improve the function a little bit more - and we are good to go. Let’s say we have a dynamic array with 129 elements - but we will have allocated memory for 256 elements… It is 127 more then we need! We don’t want to be greedy, so let’s find a way to free up the memory.

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h> // I included this just to use boolean values with
                         // neat true/false aliases
    
    int append_array_element(int **array, int *array_length,
                             int *array_alloc_length, int element,
                             bool is_last_element) {
        *array_length += 1;
        if (*array_length > *array_alloc_length || is_last_element) {
            if (is_last_element) {
                *array_alloc_length = *array_length;
            }
            else if (*array_alloc_length == 0) {
                *array_alloc_length = 1;
            } else {
                *array_alloc_length *= 2;
            }
    
            void *_tmp_array = realloc(*array, *array_alloc_length * sizeof(int));
            if (!_tmp_array) {
                printf("Error while trying to reallocate memory for an array!n");
                return -1;
            }
            *array = _tmp_array;
        }
        (*array)[*array_length - 1] = element;
    
        return 0;
    }
    

    That should be pretty straight-forward. And let’s call it two more times with 10 and 100 elements:

    int main() {
        int *array = NULL;
        int array_length = 0;
        int array_alloc_length = 0;
        bool is_last_element;
    
        int i;
        int i_max = 10;
        for (i = 0; i < i_max; i++) {
            if (i == i_max - 1)
            {
                is_last_element = true;
            } else {
                is_last_element = false;
            }
            append_array_element(&array, &array_length, &array_alloc_length,
                                 i, is_last_element);
        }
    
        printf("Our array with %d elementsn", array_length);
        for (i = 0; i < i_max; i++) {
            printf("%dn", array[i]);
        }
        printf("Array length: %d, allocated elements: %dn",
               array_length, array_alloc_length);
    
        return 0;
    }
    

    And the results are:

    Our array with 10 elements
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Array length: 10, allocated elements: 10
    
    Our array with 100 elements
    0
    1
    2
    ...
    97
    98
    99
    Array length: 100, allocated elements: 100
    

    Pretty neat, huh? Thank you for reading!